Bug Tracker

Opened 9 years ago

Closed 9 years ago

Last modified 9 years ago

#12282 closed bug (fixed)

1.8.0 regression - document ready is fired too early on IE 9/10

Reported by: [email protected] Owned by: mikesherov
Priority: high Milestone: 1.8.1
Component: core Version: 1.8.0
Keywords: Cc:
Blocked by: Blocking:



We have a weird banner system that injects an external script with document.write that triggers a regression in $(document).ready() in jQuery 1.8.0 (jQuery 1.7.2 works fine).

Basically, document ready is fired before the object defined below document ready code section is called (on IE 9 or IE10 - IE 10 is from last years Windows 8 developer preview).

I've created a minimal test case at: http://www.centarnekretnina.net/dev/test.html

The page should execute alert("test");

IE10 dev tools console outputs:

SCRIPT5007: Unable to get value of the property 'init': object is null or undefined test.html, line 20 character 5

You can download the two small files (test.html and test2.js), change the jquery version and see that this works fine on jQuery 1.7.2

Change History (31)

comment:1 Changed 9 years ago by Rick Waldron

Owner: set to [email protected]
Status: newpending

Thanks for taking the time to contribute to the jQuery project! Please provide a complete reduced test case on jsFiddle to help us assess your ticket.

Additionally, be sure to test against the jQuery Edge version to ensure the issue still exists. To get you started, use this boilerplate:  http://jsfiddle.net/FrKyN/ Open the link and click to "Fork" (in the top menu) to get started.

comment:2 in reply to:  1 Changed 9 years ago by anonymous

I can't reliably reproduce it with jsfiddle (it probably introduces more side-effects), and my version is pretty minimal already.

I've created another version:


That uses http://code.jquery.com/jquery-git.js (jQuery edge)

You may have to reload the page for the error (no "test" alert) to occur.

comment:3 Changed 9 years ago by [email protected]

Status: pendingnew

Actually I've found a way to reproduce it on jsfiddle (testing on Windows 8 dev preview - IE10)


After it loads once, click jsfiddle "Run" to run again and take a look at IE10 console (open it before you click run)

comment:4 Changed 9 years ago by mikesherov

Component: unfiledcore
Milestone: None1.8.1
Owner: changed from [email protected] to mikesherov
Priority: undecidedhigh
Status: newassigned

comment:5 Changed 9 years ago by anonymous

Here is an update that reproduces it without any external resources beyond jQuery.


comment:6 Changed 9 years ago by mikesherov

This is great, thanks.

comment:7 Changed 9 years ago by Denis

Confirmed in IE9 too.

comment:8 Changed 9 years ago by SoonDead

Confirmed in my application too.

$(document).ready() fires before all the javascript files are loaded in IE9.

Last edited 9 years ago by SoonDead (previous) (diff)

comment:9 Changed 9 years ago by mikesherov

Rather than more "me too", it would be helpful if you guys posted examples and links to see this in action.

comment:10 Changed 9 years ago by mikesherov

Keywords: needsdocs added

So, this fiddle: http://jsfiddle.net/dKDdj/4/ does not exhibit a problem with .ready(). .ready() is a deferred http://api.jquery.com/category/deferred-object/ .

If the DOM is ready when you call it, it will execute synchronously. If the DOM is not ready when you call it, it will execute asynchronously.

In the example provided, you are relying on the async execution of .ready(), which isn't a gaurantee. This is because .ready() fires a bit earlier in 1.8 because it does a new check for DOM readiness.

If someone has proof that the DOM can't be manipulated on .ready(), I'd love to hear about it.

SoonDead, Denis, do you have examples?

needs docs to re-emphasis the promisey nature of .ready()

comment:11 Changed 9 years ago by [email protected]

Here is the issue in jsFiddle thank you vrodic, we were having this issue when we just updated to 1.8 Using the mvc3, with partials this problem presents it self in many areas. It works correctly with IE7 and IE8, Chrome and Firefox.

When you first access the js fiddle link it will run correctly, press the run button it will break. if you change to jquery 1.7.2 it runs correctly it both scenarios. http://jsfiddle.net/tgo16/H6zte/4/

Test machine IE9 9.0.8112.16421, Windows 7 SP1

comment:12 Changed 9 years ago by mikesherov

markoj21, please read what I wrote. Of course it will break, as you're assuming something about .ready() that just isn't true. It isn't gauranteed to execute asynchronously.

comment:13 Changed 9 years ago by anonymous

So, it seems that in many cases (WebKit, Gecko, IE < 9) ready() currently fires asynchronously but in IE9 it does not. I get that there is no guarantee, but it is likely that many people have been making this incorrect assumption and so the change in detection logic is exposing it and causing breakage. This is going to be a headache to fix...

comment:14 Changed 9 years ago by jaubourg

I don't see how it is a headache. It's as simple as moving the call to $.ready at the end of the inline script. Where it should have been in the first place.

It's not so much that ready is asynchronous in other browsers but rather that the document is actually ready when executing the inline script in IE9. IE9 is better at detecting DOM readiness than other browsers here, seeing as, if the inline script is being executed, it means it was parsed thus so was the whole document.

Anyway, since the dom is ready, the handler is called immediately. The real problem is that our documentation doesn't emphasize the fact a handler will be called immediately if the DOM is ready, even though it's been the case since DOM readiness was first introduced in jQuery.

comment:15 Changed 9 years ago by ChrisS

I've another situation where $(document).ready() is fired too early.

I've a JSP with a default page buffer of 8kb. Which means if the buffer is full it will be flushed and the browser gets the content generated until this time.

Lets assume a client has submitted a search request and the search will take a few seconds. In case the page buffer is full, for example the header and the navigation was generated, it will be flushed to the client, before the server side search is done and has generated any content. In my case the client has already received some script blocks with a $(document).ready() call. But the javascript the $(document).ready() call should execute is at the end of the page. And due to the server side search, which takes a while, the page isn't completely generated yet. Now the Problem is that IE9 sometimes fires $(document).ready() even if the page isn't complete generated.

Below is a little JSP example which demonstrates this issue. I would expect to see "PAGE END" in the console at first. But sometimes I see "document ready" in the console at first.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
		<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
		<script type="text/javascript" src="/js/jquery-core/1.8/jquery-1.8.min.js"></script>
		<script type="text/javascript">
		$(document).ready(function() {
			console.log("document ready");

			// Force the buffer to flush (default is 8kb)
			for (int i = 0; i < (8 * 1024); i++) {
				out.write(" ");
		<h2>Sleeping 1 second (simulating server side process)</h2>
			try {
			} catch(Exception e) {

		<p><a href="?">click</a></p>

		<script type="text/javascript">
			console.log("PAGE END");

comment:16 Changed 9 years ago by dmethvin

@ChrisS, are the results consistent if there is some HTML below the "PAGE END" log, or if the JavaScript in that block does a document.write? Just curious about the conditions that might affect it.

comment:17 Changed 9 years ago by jaubourg

If that's the case, it could be the nail in the coffin of readyState === "interactive" :/

comment:18 Changed 9 years ago by jaubourg

BTW, isn't that what longLoad.php in test/data/event is supposed to test for?

comment:19 Changed 9 years ago by jaubourg

Could explain this: http://swarm.jquery.org/result/154890 though I have no clue why it wouldn't fail before.

comment:20 Changed 9 years ago by cdowns

I've had issues when a page has an .ready in the header that calls something from a script block in the body. It looks similar to an issue that requireJS had (https://github.com/requirejs/domReady/commit/a3e0dd8b6d3d3ee636ff0ca6a5a7c302d6ab33bf). The issue when debugging in IE9 seems to show up due to line 835 of core.js (changed in f5fd41252e3ae48a655c5da4a0b2910bb897b6ed):

if ( document.readyState === "complete" || ( document.readyState !== "loading" && document.addEventListener ) )

IE9 at that point is readyState === "interactive" so it goes through with the .ready, but then you get to line 379 of the .ready:

// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
		if ( !document.body ) {
			return setTimeout( jQuery.ready, 1 );

IE9 will give back a document.body that hasn't run all the scripts. Would it be better at that section to actually do the same .addEventListener stuff that is in the ready.promise instead of just calling the ready again until document.body exists? So for the case that document.body doesn't exist, couldn't you rely on the DOMContentLoaded firing like you do in the ready promise?

comment:21 Changed 9 years ago by mikesherov

@cdowns, the problem here seems to be that document.body exists, and readyState === "interactive", but DOM clearly isn't ready. I think we can fix this by changing the location in which we do Diego Perini's famous doScroll check. We'll see.

@jaubourg, it's not what longLoad.php is doing. That is a long loading iframe on a page to keep interactive going even though DOM is ready. This test case would be partial page load triggers interactive too early when DOM clearly isn't ready.

Hopefully, I can repro this. Silly IE.

comment:22 Changed 9 years ago by dmethvin

@mikesherov, maybe @cdowns has something there. If we could detect whether the browser supports DOMContentModified we could just ignore .readyState entirely, which would cover IE9 and IE10. Unfortunately, the trick we already use in support.js runs afoul of Content Security policy so we can't do it that way.

Version 0, edited 9 years ago by dmethvin (next)

comment:23 Changed 9 years ago by anonymous

@ChrisS @SoonDead @vrodic @mikesherov @jaubourg I have the same problem : (jQuery 1.8.0) - IE9 sometimes fires $(document).ready() even if the page isn't complete generated.

works fine on jQuery 1.7.2

comment:24 Changed 9 years ago by mikesherov


ChrisS and cdowns, thank you thank you thank you.

comment:25 Changed 9 years ago by Mike Sherov

Resolution: fixed
Status: assignedclosed

Fix #12282. IE has premature .readyState == "interactive". Close gh-901.

Changeset: 0f553ed0ca0c50c5f66377e9f2c6314f822e8f25

comment:26 Changed 9 years ago by ChrisS

I can confirm that the bug is fixed, now. The current version from github works fine in my test and production scenario.

Thank you, mikesherov.

comment:27 Changed 9 years ago by [email protected]

I also confirmed this behavior in IE9. It doesn't seem to matter whether you are in IE8 compatibility mode or 'edge' (eg. <meta http-equiv="X-UA-Compatible" content="IE=8,chrome=1,requiresActiveX=true" />). I noticed that ie9 was inconsistent in finding all of the items in a collection on $(document).ready; I added an alert right after my $(document).ready call and found that the alert would popup before all of the DOM was rendered. I upgraded to the github jquery source (1.8.1pre) and all is good; $(document).ready doesn't fire until the DOM is fully loaded. Thanks for getting this fixed - just can't wait for the official release of 1.8.1. There are several other issues with ie9 and jQuery 1.8, which I am hoping will be resolved in the upcoming release.

comment:28 Changed 9 years ago by [email protected]

Please, I can't see the solution. I have the same problem with IE9. Can I help me?

comment:29 in reply to:  26 Changed 9 years ago by anonymous

Please, put the file to download. Thanks

Replying to ChrisS:

I can confirm that the bug is fixed, now. The current version from github works fine in my test and production scenario.

Thank you, mikesherov.

comment:30 Changed 9 years ago by tentonaxe

Was it intended for this fix to cause IE7 and IE8 to fire document.ready later than modern browsers? http://jsfiddle.net/Camilo/PFWmS/ it now seems to wait until onload.

Edit: I guess it has always been that way.

Last edited 9 years ago by tentonaxe (previous) (diff)

comment:31 Changed 9 years ago by mikesherov

Keywords: needsdocs removed
Note: See TracTickets for help on using tickets.