在 jQuery 版本 3.1.1 中,当 document
已经加载完成后调用 .ready()
方法时,代码行 3930
到 3947
负责处理此情况。在第 3938 行,jQuery.ready
方法通过 setTimeout
被调用,但没有设置持续时间,并附有注释。
// Handle it asynchronously to allow scripts the opportunity to delay ready
这可能解释了为什么window.alert('alert 3')
可能会在window.alert('alert 2')
之前被调用。
if ( document.readyState === "complete" ||
( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
window.setTimeout( jQuery.ready );
} else {
document.addEventListener( "DOMContentLoaded", completed );
window.addEventListener( "load", completed );
}
以下的 stacksnippet 应该能够复现 OP 描述的结果。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Demo2</title>
<script src="https://code.jquery.com/jquery-3.1.1.js"></script>
<script>
$(window.document).ready(function() {
window.alert('alert 1');
});
$(function() {
window.alert('alert 2');
});
$(function() {
window.alert('alert 3');
});
</script>
</head>
<body>
</body>
</html>
另请参见completed
函数,位于3924
行。
function completed() {
document.removeEventListener( "DOMContentLoaded", completed );
window.removeEventListener( "load", completed );
jQuery.ready();
}
请查看版本为1的plnkr http://plnkr.co/edit/C0leBhYJq8CMh7WqndzH?p=preview
编辑,更新
为了确保在.ready()
中函数的执行顺序,您可以从函数调用中返回一个promise,使用.then()
在单个.ready()
调用内调用全局定义或之前在.ready()
处理程序中定义的函数。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Demo2</title>
<script src="https://code.jquery.com/jquery-3.1.1.js"></script>
<script>
function ready1(wait, index) {
return new Promise(resolve => {
setTimeout(() => {
window.alert('alert ' + index);
resolve(index)
}, wait)
})
.then((i) => console.log(i))
}
function ready2(wait, index) {
return new Promise(resolve => {
setTimeout(() => {
window.alert('alert ' + index);
resolve(index)
}, wait)
})
.then((i) => console.log(i))
}
function ready3(wait, index) {
return new Promise(resolve => {
setTimeout(() => {
window.alert('alert' + index);
resolve(index)
}, wait)
})
.then((i) => console.log(i))
}
$().ready(function() {
ready1(3000, 0)
.then(function() {
return ready2(1500, 1)
})
.then(function() {
return ready3(750, 2)
});
})
</script>
</head>
</html>