Sunday 13 January 2008

Knowing what's on your page

So in work the other day I was asked to help a colleague with an interesting error he was experiencing. In IE he would find on usually the second page load of the site IE would bomb out with an exception: "Internet Explorer cannot open the Internet site", "Operation aborted".


Now I had seen this error before and usually it was down to people forgetting or even not knowing that they had to wait for the DOM to finish loading before trying to fire off JavaScript that manipulates or uses the DOM.


Of course most of us know we can solve this by using event listeners to attach functions to load on the window.load event or my personal favourite by using some sort of .onDOMReady method. Just like the one in jQuery or YUI.


Now in this case it looked like my colleague had set up his JavaScript properly, it was using the YUI onDomReady so this wasn't the issue, so where was the problem. We ended up turning to his JavaScript JSLint'n it to see if there was something I had missed but still the code eventually validated and we still had the IE error.


So we scratched our heads and then by chance I noticed that the page with the error had a flash movie embedded into it. Now I'm very much in the camp of not liking how many developers embed flash into a page and I always use UFO (Unobtrusive Flash Object. It was at this point my colleague mentioned that he was also using UFO after seeing me use it in a few projects, as it allowed him to put alt content in place for non Flash peeps. It was at this point I realised what had happened.


In case your not fully knowledgeable on UFO, "UFO is a DOM script that detects the Flash plug-in and embeds Flash objects (files with the .swf extension)." What you can then do is replace the contents of one Div Container, say one which contains alternative content for non flash users, with a Flash object. It does this using JavaScript and I find it to be the only way of allowing flash on any sites that I work on.


Now as this JavaScript manipulates the DOM, i.e remove the contents of our Flash Div and then put our Flash object into it, it must run once the DOM is ready otherwise we run the risk of trying to manipulate the DOM before it's even ready. This is what our page was trying to do.


Now I mentioned earlier that my colleague had wrapped his JavaScript functionality into a onDomReady, now what he didn't check and I initially missed was what else was in the page and what other JavaScript was loading. In this case his new functionality was causing the page to load a little slower which meant that the UFO code, which wasn't wrapped in a nice onDomReady, was firing before the DOM had finished loading. Such that the Flash DIV wasn't actually available at the point that the UFO code was trying to run.


So we simple moved the UFO method call into our onDomReady function and we were sorted. This example clearly shows that especially when writing JavaScript you need to be aware of what else is on your page and in particular what else is interacting with it. Before writing some JavaScript that does X Y and Z take alook at the page or even site and see what else is running / loading. Not only will this allow you to ensure your code doesn't break or break anything else but you will also find if there is some code you may want to reuse.


For example I often find myself writing JavaScript that uses the YUI library as this is what i have used most however recently I was writing some new functionality for a site and started to use YUI as its what I use most, got the functionality working on my example page, then went to put it into the site and found that it was already using JQuery. I then had to go back and quickly change my code so that it used JQuery instead of YUI as using more than one JavaScript library in my opinion is stupid and means that the end user has to download far more and it will end up with page load times being sacrificed.


So when writing JavaScript ensure you know whats going on in your page before writing your code, otherwise you may end up with a situation like my colleague did or you may end up re writing you code like I did. And you may find that your work load is actually reduced as you may be able to reuse code that's already in the page.

No comments: