Opened 9 years ago

Closed 9 years ago

Last modified 9 years ago

#10918 closed defect (fixed)

dojo.addOnLoad can still cause "Operation Aborted"

Reported by: kaczmar2 Owned by: anonymous
Priority: high Milestone: 1.5
Component: Core Version: 1.4.2
Keywords: dojoAddOnLoad skipIeDomLoaded "Operation Aborted" Cc:
Blocked By: Blocking:

Description

In 1.4.1, there is a new djConfig parameter: skipIeDomLoaded The explanation offered in the description of this new parameter was exactly what our application was experiencing (we are using Dojo 1.3.2:) "For IE only, skip the DOMContentLoaded hack used. Sometimes it can cause an Operation Aborted error if the rest of the page triggers script defers before the DOM is ready. If this config value is set to true, then dojo.addOnLoad callbacks will not be triggered until the page load event, which is after images and iframes load." However, waiting util the page load event can be too conservative, which I am assuming is what the flag was introduced - don't use it unless you see this issue. I think there is a better way. A colleague of mine traced the "Operation Aborted" issue back to this code in host_env_browser.js: if(!dojo.config.afterOnLoad){

document.write('<scr'+'ipt defer src=":" '

+ 'onreadystatechange="if(this.readyState==\'complete\'){' + dojo._scopeName + '._loadInit();}">' + '</scr'+'ipt>'

);

} The issue is this: when this dynamically included script is executed, it does a check on this.readyState. However, "this" is the <script> scope, not the document scope. We found that many times, even though the script.readyState (this.readyState) was "complete", the document.readyState was not "complete". This resulted in _loadInit() being called when the DOM was not ready, and resulting in the "Operation Aborted" error message. The code above was replaced with the following: if(!dojo.config.afterOnLoad){

document.write( '<scr'+'ipt defer src=\':\

+ ' onreadystatechange=\ + ' if( this.readyState == "complete" ) {' + ' if( document.readyState != "complete" ) {' + ' var fn =\n' + ' function() {\n' + ' if( document.readyState == "complete" ) {\n' + ' document.detachEvent( "onreadystatechange", fn ) ;\n' + ' fn = void 0 ;\n' + ' ' + dojo._scopeName + '._loadInit() ;\n' + ' }\n' + ' } ;\n' + ' document.attachEvent( "onreadystatechange", fn ) ;\n' + ' }\n' + ' else {\n' + ' ' + dojo._scopeName + '._loadInit();\n' + ' }\n' + ' }' + ' \

+ '>' + '</scr'+'ipt>'

);

} This essentially hooks a callback to the document's onreadystatechange listener, if the document.readyState is not "complete". Once the DOM is ready, the callback is detached from the document onreadystatechange listener. This is more performant than waiting for the page load event to occur. It's been in our production environment for awhile how, and we continue to use it with no problems.

Attachments (1)

hostenv_browser.js (16.5 KB) - added by kaczmar2 9 years ago.

Download all attachments as: .zip

Change History (6)

comment:1 Changed 9 years ago by kaczmar2

Added an attachment: hostenv_browser.js, which demonstrates the fix.

Changed 9 years ago by kaczmar2

Attachment: hostenv_browser.js added

comment:2 Changed 9 years ago by James Burke

Resolution: fixed
Status: newclosed

(In [21706]) Fixes #10918, move away from old IE domcontentloaded approximation to something that should work better. Made detection of page loaded after dojo is added to the page better too.

comment:3 Changed 9 years ago by James Burke

(In [21727]) Refs #10918, make the IE interval cancel more robust.

comment:4 Changed 9 years ago by bill

Milestone: tbd1.5

comment:5 Changed 9 years ago by bill

(In [22103]) fixes #11106: fixed an edge case problem for the new IE dom ready approximation

Note: See TracTickets for help on using tickets.