Dushan Hanuska

This problem was a rather strange one (JRA-14423). I like tooling with JavaScript but sometimes it surprises me how many differences there may be between various browsers.

Using JavaScript libraries has its benefits. A library may give us another abstraction layer - a layer that if designed well can hide differences between browsers and provide a uniform interface. Another reason to use a library is that if a library is popular and widely used, it is very likely well tested on probably more browsers than you are willing to test your code on.

However, no library is perfect. The problem we encountered and I am about to describe happened with Yahoo! User Interface library. In JIRA, we have a little panel that pops up and shows a list of links. Getting this list is not very expensive, but taken into account that this panel would be accessible from almost every single page of JIRA, it would be quite heavy on our server. Especially taking into consideration that the link that pops this panel up would not be clicked very often.

The solution: every time a user clicks the link that pops up this panel, we make an AJAX request for the list of URLs we want to display. And of course we display a little loading bar until we have that list of URLs. We made it into a little widget that is created when the page loads. We used YAHOO.util.Event.onDOMReady event handler. Strangely enough Internet Explorer sends this event too early and DOM is not ready yet. As a result Internet Explorer reported the following error in the middle of page loading.

JIRA_TST-1_Popup.png

After that the loaded content disappeared and was replaced with a standard error message.

JIRA_TST-1_Error.png

If this happens to you with your code, don't panic. There is an easy fix. If the execution of your code can wait a little bit longer, run your code on 'load' event rather than on 'DOMReady'. In terms of YUI methods, replace

YAHOO.util.Event.onDOMReady(handler);

with

YAHOO.util.Event.addListener(window, 'load', handler);

According to D. Flannagan - JavaScript The Definitive Guide

  • window.onload = handler
  • <body onload="handler" ... >
  • <frameset onload="handler" ... >
The onload property of a Window specifies an event handler function that is invoked when a document or frameset is completely loaded into its window or frame.

Problem solved. The code execution is a bit delayed, but it is guaranteed to work on Internet Explorer without strange errors*.

* strange errors - most (if not all) browsers work fine, only IE has a problem

8 Comment(s)

I had the same problem a while ago with IE6. The problem occurred every time an DOM element was accessed before IE read its end tag.

Therefore one solution would be to add a container and put the call to your function after the end tag. For example: <div id="theContainer">some content</div><script type="...">//your function call that works inside the container</script>

In common this approach doesn't seem to be a problem. The only case where it is a bit tricky to use is when you want to work with the body. You could put your caller script tag at the end of the body and call with a little timeout but there is no guarantee of correct working in this case.

However if you can delay execution of your function util onload this is the better solution/workaround. If they simply could manage to implement the DOMContentLoaded event...

By Guest at March 24, 2008 11:40 AM

The "Operation Aborted" is probably caused by this IE 6 problem.

You might also find that doing something like this works:

YAHOO.util.Event.onDOMReady(function(setTimeout(foo, 0)));

where foo is the function that your original onDOMReady called.

This comment (and the original article) provide some information on why setTimeout can help in situations like this.

That said, there do appear to be a few weird edge cases that onDOMReady struggles with, the tricky thing has been finding test cases that demonstrate the problems clearly so that they can be described in a YUI bug report. Looks like you guys might have found one.

By Walter Rumsby at March 25, 2008 11:58 PM

I use a different library, but I think that most domready-checking is based on Dean Edwards' fine work, the methodology being that when you place a script in the head with a defer="defer" property, that script isn't loaded until the DOM is closed. Then, using an onload command for that script, you infer that the DOM is closed, and you trigger your domready events. The Operation Aborted error is really a symptom, usually indicating that you're trying to add something directly to document.body or some larger container div. If domready fires early and your container isn't closed, you'll trip the Operation Aborted error. This can also cause errors on the page when you have domready events addressing elements that aren't even present on the page yet. It won't trigger Operation Aborted, but you'll get an error saying, roughly, "$('mydiv') has no properties".

I don't fully understand what causes the domready-triggering deferred script to load, but I've been looking for the trigger for some time. I work for a fairly large website on pages that have code from a number of different sources, including advertisers, so I don't have complete control over what goes into them.

What I've seen is that in some cases, document.write-ing and innerHTML=-ing to a page can cause the deferred script to load. It seems to me that something about converting raw text into DOM elements triggers the problem. I've often found that converting raw text into DOM elements before inserting them into the DOM resolves the issue. But not always.

A case I've been wrestling with today may have helped me to narrow it down, but I still need to test. An ad was document.write-ing a style element, and I think that specifically was triggering the deferred script to load. So maybe document.write-ing or innerHTML=-ing script and style tags can cause the problem. But not always.

Want a quick way to see what's probably causing IE to load the deferred script that triggers the domready events? I'm going to write this in MooTools (the library we use) syntax, but I'm sure you can easily translate it:

window.addEvent('domready', function() {
alert(document.body.innerHTML.substring(document.body.innerHTML.length-500));
});

By Andrew Lottmann at March 27, 2008 11:26 AM

When do you plan to fix this issue in Jira? I don't have access to view JRA-14423.

By Hank Roark at April 23, 2008 7:03 AM

Sorry about that, JRA-14423 had an issue security set - preventing you from seeing it. It is visible now. It was not visible because it was in the code for JIRA 4.0 that has not been released yet and was fixed before it will be released.

By Dushan Hanuska at April 23, 2008 4:37 PM

DOMReady using defer scripts is quite buggy. Try to use this variant instead:

// Continually check to see if the document is ready
var timer = function()
{
try
{
// If IE is used, use the trick by Diego Perini
// http://javascript.nwbox.com/IEContentLoaded/
if (qx.bom.client.Engine.MSHTML || document.readyState != "loaded" && document.readyState != "complete") {
document.documentElement.doScroll("left");
}

nativeWrapper();
}
catch(error) {
setTimeout(timer, 100);
}
};

timer();

This is part of the qooxdoo project (http://qooxdoo.org) (API available under: http://demo.qooxdoo.org/devel/apiviewer/#qx.event.handler.DomReady)

The idea behind this piece is to start an "interval" which detects is the document is scrollable. This should be the better alternative and worked in all our test cases.

By Sebastian Werner at May 7, 2008 12:52 PM

if you are developing application with ASP.NET then use ClientScriptManager's RegisterStartupScript method instead of YAHOO.util.Event.onDOMReady(handler);

It will inject javascript method with rendered HTML output & will be invoked after complete page rendering.

In JS file :-
onPageLoad = function() {

new MyControls({
ctrlCollection : Yahoo.util.Dom.getElementsByClassName("CSS-Class Name")
});
}

In CS file :-

Page.ClientScript.RegisterStartupScript(typeof(MyPage), "LoadPage", "onPageLoad();", true);

Please avoid to use onDOMReady event with IE

Regards
Lalit Dwivedi

By Lalit Dwivedi at October 14, 2008 7:11 AM

i have problem in IE while using mootools lib
window.addEvent('domready', function() {

Sexy = new SexyAlertBox();
});

ERROR: Sexy is undefined in IE.
Please let me know i can write instead of 'domready'

By shetty at January 29, 2009 9:51 AM

Post a comment

If you haven't left a comment here before, you may need to be approved by the site owner before your comment will appear. Until then, it won't appear on the entry. Thanks for waiting.





Remember personal info?

Type the characters you see in the picture above.