Bug Tracker

Ticket #7352 (closed bug: fixed)

Opened 4 years ago

Last modified 2 years ago

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

Reported by: thomas.switzer@… Owned by: john
Priority: blocker Milestone: 1.4.4
Component: event Version: 1.4.3
Keywords: Cc:
Blocking: Blocked by:

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.

Change History

comment:1 Changed 4 years ago by john

#7344 is a duplicate of this ticket.

comment:2 Changed 4 years ago by john

  • Owner set to john
  • Status changed from new to assigned
  • Component changed from unfiled to event
  • Milestone changed from 1.5 to 1.4.4

comment:3 Changed 4 years ago by john

  • Priority changed from undecided to blocker

comment:4 Changed 4 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 4 years ago by Hannes

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

comment:6 Changed 4 years ago by rwaldron

#7447 is a duplicate of this ticket.

comment:7 Changed 4 years ago by John Resig

  • Status changed from assigned to closed
  • Resolution set to fixed

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 4 years ago by andreighiuta@…

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

comment:9 Changed 4 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.