#7352 closed bug (fixed)
Appending iframe on "ready" causes re-trigger of "ready"
Reported by: | Owned by: | john | |
---|---|---|---|
Priority: | blocker | Milestone: | 1.4.4 |
Component: | event | Version: | 1.4.3 |
Keywords: | Cc: | ||
Blocked by: | Blocking: |
Description
What is affected (at least)
This happens (at least) with jQuery 1.4.2 and 1.4.3 in Chrome 7.0.517.41 and Safari 4.0.4 on Mac OS X 10.6.3.
How to reproduce
- Create 2 $(document).ready(function() { ... }) calls. In the first one, do something w/ a side-effect (eg. append an element to the DOM). In the 2nd one append an empty iframe (ie. $("body").append($("<iframe />"))).
- Open up the web page in the browsers listed above. Refresh a few times.
What is expected to happen
Both functions are called once and no exception is thrown.
What actually happens:
Sometimes the $(document).ready functions are called twice. An exception is thrown (eg. Uncaught TypeError: Cannot ready property '3' of null).
Working (ie. broken) example
Try hitting run a couple of times. The problem is intermittent and doesn't always appear (and may not for you). It seems to be affected by page load times and appears more often on a local version (ie. copy/paste the code to a local copy, load it, and refresh a few times).
The problem
When an (empty) iframe is appended to the DOM during jQuery.ready (ie. within a function triggered by "ready"), it sometimes causes "ready" to be retriggered. This seems to happen within the function that appended the element. All the functions bound to "ready" are called again. jQuery.ready then sets the variable readyList to null after looping through all the functions. Then, when the original jQuery.ready call goes to loop onto the next bound function, it throws an exception because readyList was set to null.
Change History (9)
comment:1 Changed 12 years ago by
comment:2 Changed 12 years ago by
Component: | unfiled → event |
---|---|
Milestone: | 1.5 → 1.4.4 |
Owner: | set to john |
Status: | new → assigned |
comment:3 Changed 12 years ago by
Priority: | undecided → blocker |
---|
comment:4 Changed 12 years ago by
Same here. The second invocation is passed an actual event for the "wait" parameter, not a boolean. The event is of type "load". Stack trace for the second invocation look like this (most recent frame at the top):
jQuery.jQuery.extend.ready jquery-1.4.3.js:414 FB.provide.insertIframe facebook.js:2138 FB.provide._insertIframe facebook.js:3897 FB.provide.hidden facebook.js:3850 FB.provide.ui facebook.js:3657 FB.provide.getLoginStatus facebook.js:1367 init facebook.js:21 filters.filters index.js:331 (anonymous function) tools.js:180 jQuery.jQuery.extend.ready jquery-1.4.3.js:438 jQuery.DOMContentLoaded jquery-1.4.3.js:868
Line facebook.js:2138 does something like divNode.appendChild( iframeNode )
.
Could this issue be cause by the fact that jQuery.bindReady registers two handlers, for load as well as for DOMContentLoaded?
if ( document.addEventListener ) { // Use the handy event callback document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); // A fallback to window.onload, that will always work window.addEventListener( "load", jQuery.ready, false );
It seems like the reentrance is caused by the "load" event.
Chrome 7.0.517.41, Mac OS X 10.6.4 (10F569), jQuery 1.4.3
comment:5 Changed 12 years ago by
I just verified that removing the line that registers the "load" handler prevents the reentrance.
comment:7 Changed 12 years ago by
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
Make sure that if an additional load event is triggered (such as an iframe being dynamically injected in DOM ready) the ready event isn't triggered twice. Fixes #7352.
Changeset: 983548f8ebc3fcd1bb4600bc4b740cb8a5d4c48b
comment:8 Changed 12 years ago by
Just downloaded 1.4.4 and this still occurs in IE7,8, doesn't occur in other browsers
comment:9 Changed 12 years ago by
The please submit a reduced test case, which reproduces the issue you are experiencing, on http://jsfiddle.net. So that we can investigate this issue further.
http://jsfiddle.net/jitter/HrvWc/46/ is working for me in IE8
#7344 is a duplicate of this ticket.