Monday, February 25, 2008

Be Weary of Event.observe()

In a day when I thought I was safe from all the cross-browser incompatibilities, I've been bitten in the ass once again. If you're a bit confused as to why I would think such things, you obviously haven't used a Javascript framework like Prototype. Up to this point, the only cross-browser issues I've concerned myself with, are CSS ones--and boy, there still are many, even with IE7 around). So what's my latest beef with Microsoft's craptacular Internet browser? Before I can answer that, I have to take a brief moment to explain Event.observe().

Event.observe() abstracts element.addEventListener() and element.attachEvent() which basically allows a 1-to-many relationship between an element's event and its listeners. It's a great idea, and comes in handy for me personally for many projects I work on.

In and of itself, Event.observe() is pretty easy and works without problem; however, one would assume that when push comes to shove and the event gets triggered, the listeners would be called in the order they were registered in. Well, those making that assumption would be mostly correct. This is where the browser from Bizarro World, Internet "Motherf**king" Explorer, comes in. IE appears to do the exact opposite.

To better explain, I'll use some code for example. We'll use three files: index.html (I've omitted the doctype for brevity), first.js, and second.js.

index.html
<html>
<head>
<title>Mai File</title>
<script type="text/javascript" src="first.js"></script>
<script type="text/javascript" src="second.js"></script>
</head>

<body>
</body>
</html>


Note: first.js came before second.js.

first.js

var a = "first";
Event.observe(window, 'load', function(event)
{
alert("first:" + a);
});


And second.js is almost identical.

second.js

var a = "second";
Event.observe(window, 'load', function(event)
{
alert("second:" + a);
});


When we open up our favorite browser (if it's Internet Explorer, you should be castrated), and visit our page, two alerts will pop up: "first:second", and "second:second". Left of the colon tells us what script is calling the alert() (in a matter of speaking). On the right of the colon, it tells us which script set the variable 'a' last. So according to our results, the variable 'a' was set to "second" last, which second.js was parsed second like we expected. And the alerts came in the order we also expected them.

Now we try this very same page in IE, and what do we get? "second:second", and "first:second". The exact opposite. The files were parsed in the correct order, but the event listeners were called in the opposite order.

Why this is? I have no idea. What this means though is, you can't write event listeners that depend on other event listeners of the same event. This can be quite annoying for those of us who use the window.onload event for bootstrapping and have a desired "order of operations."

Labels: , ,

2 Comments:

Anonymous Anonymous said...

Hello. This post is likeable, and your blog is very interesting, congratulations :-). I will add in my blogroll =). If possible gives a last there on my blog, it is about the Vinho, I hope you enjoy. The address is http://vinho-brasil.blogspot.com. A hug.

12:15 AM  
Blogger Unknown said...

Yeah, I just ran into this today... freaking annoying as can be. Makes me want to hack prototype to enforce execution by order of inclusion.

5:56 PM  

Post a Comment

<< Home