mirror of
https://github.com/jquery/jquery.git
synced 2025-01-10 18:24:24 +00:00
Fix #10067. Create jQuery.quickReady; closes gh-736.
Allows us to get to the ready state sooner by not waiting for iframes to load. If that causes backcompat pain, use `jQuery.quickReady = false` as prescribed by your developer.
This commit is contained in:
parent
58ed62ed12
commit
54fab3174c
16
src/core.js
16
src/core.js
@ -375,6 +375,9 @@ jQuery.extend({
|
|||||||
// the ready event fires. See #6781
|
// the ready event fires. See #6781
|
||||||
readyWait: 1,
|
readyWait: 1,
|
||||||
|
|
||||||
|
// should we fire ready on readyState "interactive" ?
|
||||||
|
quickReady: true,
|
||||||
|
|
||||||
// Hold (or release) the ready event
|
// Hold (or release) the ready event
|
||||||
holdReady: function( hold ) {
|
holdReady: function( hold ) {
|
||||||
if ( hold ) {
|
if ( hold ) {
|
||||||
@ -386,6 +389,12 @@ jQuery.extend({
|
|||||||
|
|
||||||
// Handle when the DOM is ready
|
// Handle when the DOM is ready
|
||||||
ready: function( wait ) {
|
ready: function( wait ) {
|
||||||
|
// user wasn't necessarily given the chance to set jQuery.quickReady before bindReady
|
||||||
|
// so we check here for quickReady instead
|
||||||
|
if ( !jQuery.quickReady && document.readyState === "interactive" ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Either a released hold or an DOMready/load event and not yet ready
|
// Either a released hold or an DOMready/load event and not yet ready
|
||||||
if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) {
|
if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) {
|
||||||
// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
|
// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
|
||||||
@ -420,9 +429,9 @@ jQuery.extend({
|
|||||||
|
|
||||||
// Catch cases where $(document).ready() is called after the
|
// Catch cases where $(document).ready() is called after the
|
||||||
// browser event has already occurred.
|
// browser event has already occurred.
|
||||||
if ( document.readyState === "complete" ) {
|
if ( document.readyState !== "loading" ) {
|
||||||
// Handle it asynchronously to allow scripts the opportunity to delay ready
|
// Handle it asynchronously to allow scripts the opportunity to delay ready
|
||||||
return setTimeout( jQuery.ready, 1 );
|
setTimeout( jQuery.ready, 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mozilla, Opera and webkit nightlies currently support this event
|
// Mozilla, Opera and webkit nightlies currently support this event
|
||||||
@ -915,6 +924,7 @@ rootjQuery = jQuery(document);
|
|||||||
// Cleanup functions for the document ready method
|
// Cleanup functions for the document ready method
|
||||||
if ( document.addEventListener ) {
|
if ( document.addEventListener ) {
|
||||||
DOMContentLoaded = function() {
|
DOMContentLoaded = function() {
|
||||||
|
jQuery.quickReady = true;
|
||||||
document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
|
document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
|
||||||
jQuery.ready();
|
jQuery.ready();
|
||||||
};
|
};
|
||||||
@ -922,7 +932,7 @@ if ( document.addEventListener ) {
|
|||||||
} else if ( document.attachEvent ) {
|
} else if ( document.attachEvent ) {
|
||||||
DOMContentLoaded = function() {
|
DOMContentLoaded = function() {
|
||||||
// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
|
// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
|
||||||
if ( document.readyState === "complete" ) {
|
if ( document.readyState === "complete" || ( jQuery.quickReady && document.readyState === "interactive" ) ) {
|
||||||
document.detachEvent( "onreadystatechange", DOMContentLoaded );
|
document.detachEvent( "onreadystatechange", DOMContentLoaded );
|
||||||
jQuery.ready();
|
jQuery.ready();
|
||||||
}
|
}
|
||||||
|
32
test/data/event/asyncQuickReadyFalse.html
Normal file
32
test/data/event/asyncQuickReadyFalse.html
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="content-type" content="text/html; charset=utf-8">
|
||||||
|
<title>Test case for jQuery ticket #10067</title>
|
||||||
|
<script type="text/javascript">
|
||||||
|
|
||||||
|
// ready should fire callback after the iframe fires the callback
|
||||||
|
setTimeout(function () {
|
||||||
|
el = document.createElement('script');
|
||||||
|
el.type = 'text/javascript';
|
||||||
|
el.onload = function () {
|
||||||
|
jQuery.quickReady = false;
|
||||||
|
jQuery(document).ready(function () {
|
||||||
|
// unfortunately, Opera 11.6 and lower has a bug where
|
||||||
|
// document.readyState is "complete" before all subresources
|
||||||
|
// are loaded, so we need this check here for tests to pass
|
||||||
|
if ( document.readyState !== "complete" ) {
|
||||||
|
window.parent.iframeCallback(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
document.getElementsByTagName('head')[0].appendChild(el);
|
||||||
|
el.src = "../include_js.php";
|
||||||
|
}, 1000);
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<!-- long loading iframe -->
|
||||||
|
<iframe src="longLoad.php?sleep=3&return=true" style="width: 1px; height: 1px"></iframe>
|
||||||
|
</body>
|
||||||
|
</html>
|
30
test/data/event/asyncQuickReadyTrue.html
Normal file
30
test/data/event/asyncQuickReadyTrue.html
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="content-type" content="text/html; charset=utf-8">
|
||||||
|
<title>Test case for jQuery ticket #10067</title>
|
||||||
|
<script type="text/javascript">
|
||||||
|
// browsers that implement the non-standard event API will load the iframe
|
||||||
|
// before loading up jQuery, so quickReady has no effect here
|
||||||
|
if( document.attachEvent ){
|
||||||
|
window.parent.iframeCallback(true);
|
||||||
|
} else {
|
||||||
|
setTimeout(function () {
|
||||||
|
el = document.createElement('script');
|
||||||
|
el.type = 'text/javascript';
|
||||||
|
el.onload = function () {
|
||||||
|
jQuery(document).ready(function () {
|
||||||
|
window.parent.iframeCallback(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
document.getElementsByTagName('head')[0].appendChild(el);
|
||||||
|
el.src = "../include_js.php";
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<!-- long loading iframe -->
|
||||||
|
<iframe src="longLoad.php?sleep=30&return=false" style="width: 1px; height: 1px"></iframe>
|
||||||
|
</body>
|
||||||
|
</html>
|
6
test/data/event/longLoad.php
Normal file
6
test/data/event/longLoad.php
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?php
|
||||||
|
sleep((int)$_GET['sleep']);
|
||||||
|
?>
|
||||||
|
<script type="text/javascript">
|
||||||
|
window.parent.parent.iframeCallback(<?php echo $_GET['return'];?>);
|
||||||
|
</script>
|
17
test/data/event/syncReady.html
Normal file
17
test/data/event/syncReady.html
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="content-type" content="text/html; charset=utf-8">
|
||||||
|
<title>Test case for jQuery ticket #10067</title>
|
||||||
|
<script type="text/javascript" src="../include_js.php"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<script type="text/javascript">
|
||||||
|
jQuery(document).ready(function () {
|
||||||
|
window.parent.iframeCallback(true);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<!-- long loading iframe -->
|
||||||
|
<iframe src="longLoad.php?sleep=10&return=false" style="width: 1px; height: 1px"></iframe>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -21,7 +21,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
jQuery(function() {
|
jQuery(function() {
|
||||||
window.parent.supportCallback( jQuery( "body" ).css( "backgroundColor" ), jQuery.support );
|
window.parent.iframeCallback( jQuery( "body" ).css( "backgroundColor" ), jQuery.support );
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<body>
|
<body>
|
||||||
<script src="../include_js.php"></script>
|
<script src="../include_js.php"></script>
|
||||||
<script>
|
<script>
|
||||||
jQuery(function() { window.parent.supportCallback( document.compatMode, jQuery.support.boxModel ) });
|
jQuery(function() { window.parent.iframeCallback( document.compatMode, jQuery.support.boxModel ) });
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
<html>
|
|
||||||
<head>
|
|
||||||
<script src="../include_js.php"></script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -7,14 +7,11 @@
|
|||||||
background: url('http://s1.postimage.org/2d2r8xih0/body_background.png');
|
background: url('http://s1.postimage.org/2d2r8xih0/body_background.png');
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<script src="../../../src/core.js"></script>
|
<script src="../include_js.php"></script>
|
||||||
<script src="../../../src/callbacks.js"></script>
|
|
||||||
<script src="../../../src/deferred.js"></script>
|
|
||||||
<script src="../../../src/support.js"></script>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<script>
|
<script>
|
||||||
window.parent.supportCallback();
|
window.parent.iframeCallback();
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -192,7 +192,7 @@ function url(value) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
function loadFixture() {
|
function loadFixture() {
|
||||||
var src = "./data/" + fileName + ".html?" + parseInt( Math.random()*1000, 10 ),
|
var src = url("./data/" + fileName + ".html"),
|
||||||
iframe = jQuery("<iframe />").css({
|
iframe = jQuery("<iframe />").css({
|
||||||
width: 500, height: 500, position: "absolute", top: -600, left: -600, visibility: "hidden"
|
width: 500, height: 500, position: "absolute", top: -600, left: -600, visibility: "hidden"
|
||||||
}).appendTo("body")[0];
|
}).appendTo("body")[0];
|
||||||
@ -200,6 +200,29 @@ function url(value) {
|
|||||||
return iframe;
|
return iframe;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.testIframeWithCallback = function( title, fileName, func ) {
|
||||||
|
|
||||||
|
test( title, function() {
|
||||||
|
var iframe;
|
||||||
|
|
||||||
|
stop();
|
||||||
|
window.iframeCallback = function() {
|
||||||
|
var self = this,
|
||||||
|
args = arguments;
|
||||||
|
setTimeout(function() {
|
||||||
|
window.iframeCallback = undefined;
|
||||||
|
iframe.remove();
|
||||||
|
func.apply( self, args );
|
||||||
|
func = function() {};
|
||||||
|
start();
|
||||||
|
}, 0 );
|
||||||
|
};
|
||||||
|
iframe = jQuery( "<div/>" ).append(
|
||||||
|
jQuery( "<iframe/>" ).attr( "src", url("./data/" + fileName + ".html") )
|
||||||
|
).appendTo( "body" );
|
||||||
|
});
|
||||||
|
}
|
||||||
}());
|
}());
|
||||||
|
|
||||||
// Sandbox start for great justice
|
// Sandbox start for great justice
|
||||||
|
@ -2794,6 +2794,26 @@ test("fixHooks extensions", function() {
|
|||||||
jQuery.event.fixHooks.click = saved;
|
jQuery.event.fixHooks.click = saved;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testIframeWithCallback( "jQuery.ready sync load", "event/syncReady", function( isOk ) {
|
||||||
|
expect(1);
|
||||||
|
ok( isOk, "jQuery loaded synchronously fires ready before all sub-resources are loaded" );
|
||||||
|
});
|
||||||
|
|
||||||
|
// async loaded tests expect jQuery to be loaded as a single file
|
||||||
|
// if we're not doing PHP concat, then we fall back to document.write
|
||||||
|
// which breaks order of execution on async loaded files
|
||||||
|
if ( hasPHP ) {
|
||||||
|
testIframeWithCallback( "jQuery.ready async load with quickReady true", "event/asyncQuickReadyTrue", function( isOk ) {
|
||||||
|
expect(1);
|
||||||
|
ok( isOk, "jQuery loaded asynchronously with quickReady true fires ready before all sub-resources are loaded" );
|
||||||
|
});
|
||||||
|
|
||||||
|
testIframeWithCallback( "jQuery.ready async load with quickReady false", "event/asyncQuickReadyFalse", function( isOk ) {
|
||||||
|
expect(1);
|
||||||
|
ok( isOk, "jQuery loaded asynchronously with quickReady false fires ready after all sub-resources are loaded" );
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
(function(){
|
(function(){
|
||||||
// This code must be run before DOM ready!
|
// This code must be run before DOM ready!
|
||||||
var notYetReady, noEarlyExecution,
|
var notYetReady, noEarlyExecution,
|
||||||
|
@ -1,37 +1,10 @@
|
|||||||
module("support", { teardown: moduleTeardown });
|
module("support", { teardown: moduleTeardown });
|
||||||
|
|
||||||
function supportIFrameTest( title, url, noDisplay, func ) {
|
testIframeWithCallback( "proper boxModel in compatMode CSS1Compat (IE6 and IE7)", "support/boxModelIE", function( compatMode, boxModel ) {
|
||||||
|
|
||||||
if ( noDisplay !== true ) {
|
|
||||||
func = noDisplay;
|
|
||||||
noDisplay = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
test( title, function() {
|
|
||||||
var iframe;
|
|
||||||
|
|
||||||
stop();
|
|
||||||
window.supportCallback = function() {
|
|
||||||
var self = this,
|
|
||||||
args = arguments;
|
|
||||||
setTimeout( function() {
|
|
||||||
window.supportCallback = undefined;
|
|
||||||
iframe.remove();
|
|
||||||
func.apply( self, args );
|
|
||||||
start();
|
|
||||||
}, 0 );
|
|
||||||
};
|
|
||||||
iframe = jQuery( "<div/>" ).css( "display", noDisplay ? "none" : "block" ).append(
|
|
||||||
jQuery( "<iframe/>" ).attr( "src", "data/support/" + url + ".html" )
|
|
||||||
).appendTo( "body" );
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
supportIFrameTest( "proper boxModel in compatMode CSS1Compat (IE6 and IE7)", "boxModelIE", function( compatMode, boxModel ) {
|
|
||||||
ok( compatMode !== "CSS1Compat" || boxModel, "boxModel properly detected" );
|
ok( compatMode !== "CSS1Compat" || boxModel, "boxModel properly detected" );
|
||||||
});
|
});
|
||||||
|
|
||||||
supportIFrameTest( "body background is not lost if set prior to loading jQuery (#9238)", "bodyBackground", function( color, support ) {
|
testIframeWithCallback( "body background is not lost if set prior to loading jQuery (#9238)", "support/bodyBackground", function( color, support ) {
|
||||||
expect( 2 );
|
expect( 2 );
|
||||||
var i,
|
var i,
|
||||||
passed = true,
|
passed = true,
|
||||||
@ -56,7 +29,7 @@ supportIFrameTest( "body background is not lost if set prior to loading jQuery (
|
|||||||
ok( passed, "Same support properties" );
|
ok( passed, "Same support properties" );
|
||||||
});
|
});
|
||||||
|
|
||||||
supportIFrameTest( "A background on the testElement does not cause IE8 to crash (#9823)", "testElementCrash", function() {
|
testIframeWithCallback( "A background on the testElement does not cause IE8 to crash (#9823)", "support/testElementCrash", function() {
|
||||||
expect(1);
|
expect(1);
|
||||||
ok( true, "IE8 does not crash" );
|
ok( true, "IE8 does not crash" );
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user