Bug Tracker

Opened 12 years ago

Closed 12 years ago

Last modified 11 years ago

#7352 closed bug (fixed)

Appending iframe on "ready" causes re-trigger of "ready"

Reported by: [email protected] Owned by: john
Priority: blocker Milestone: 1.4.4
Component: event Version: 1.4.3
Keywords: Cc:
Blocked by: Blocking:


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

  1. 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 />"))).
  2. 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 john

#7344 is a duplicate of this ticket.

comment:2 Changed 12 years ago by john

Component: unfiledevent
Owner: set to john
Status: newassigned

comment:3 Changed 12 years ago by john

Priority: undecidedblocker

comment:4 Changed 12 years ago by Hannes

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 Hannes

I just verified that removing the line that registers the "load" handler prevents the reentrance.

comment:6 Changed 12 years ago by Rick Waldron

#7447 is a duplicate of this ticket.

comment:7 Changed 12 years ago by John Resig

Resolution: fixed
Status: assignedclosed

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 [email protected]

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 jitter

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

Note: See TracTickets for help on using tickets.