Skip to main content

Bug Tracker

Side navigation

#7352 closed bug (fixed)

Opened October 29, 2010 06:34PM UTC

Closed November 09, 2010 06:44PM UTC

Last modified March 10, 2012 02:15AM UTC

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

Reported by: thomas.switzer@gmail.com 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

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

http://jsfiddle.net/HrvWc/

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.

Attachments (0)
Change History (9)

Changed October 29, 2010 08:53PM UTC by john comment:1

#7344 is a duplicate of this ticket.

Changed October 29, 2010 08:54PM UTC by john comment:2

component: unfiledevent
milestone: 1.51.4.4
owner: → john
status: newassigned

Changed October 29, 2010 08:54PM UTC by john comment:3

priority: undecidedblocker

Changed November 03, 2010 11:55PM UTC by Hannes comment:4

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

Changed November 04, 2010 12:04AM UTC by Hannes comment:5

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

Changed November 09, 2010 01:23PM UTC by rwaldron comment:6

#7447 is a duplicate of this ticket.

Changed November 09, 2010 06:44PM UTC by John Resig comment:7

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

Changed December 02, 2010 10:26AM UTC by andreighiuta@shareforce.eu comment:8

Just downloaded 1.4.4 and this still occurs in IE7,8, doesn't occur in other browsers

Changed December 02, 2010 04:57PM UTC by jitter comment:9

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