网页浏览器上的 JavaScript 是单线程运行的(除非使用 Web Workers),因此,如果你的 JavaScript 代码正在运行,就意味着没有其他 JavaScript 代码在运行。
为了尽可能确保你的脚本在页面上所有其他 JavaScript 文件都被下载、执行并完成所有渲染之后才运行,建议采取以下措施:
- 将包含你的代码的 script 标签放在文件的最末端。
- 在标签上使用
defer
和 async
属性(它们将被不支持它们的浏览器忽略,但目标是让你的脚本尽可能地排在最后)。
- 通过 DOM2 的方式挂钩 window 的 load 事件(例如,在支持标准的浏览器上使用 addEventListener,或在旧版本的 IE 上使用 attachEvent)。
- 在 load 事件中,使用 setTimeout 延迟 0ms 后再执行你的代码(实际上并不是真正的零,而是稍微长一点的时间)。
所以,script 标签应该这样写:
<script async defer src="yourfile.js"></script>
...以及yourfile.js
:
(function() {
if (window.addEventListener) {
window.addEventListener("load", loadHandler, false);
}
else if (window.attachEvent) {
window.attachEvent("onload", loadHandler);
}
else {
window.onload = loadHandler;
}
function loadHandler() {
setTimeout(doMyStuff, 0);
}
function doMyStuff() {
}
})();
那并不意味着其他代码不会在以后运行(例如,通过使用
setTimeout
,就像我们之前所做的那样,但拥有更长的超时时间)。
因此,有一些事情可以尝试最后运行,但我认为除非完全控制页面和正在运行它的脚本,否则没有任何方法可以保证最后运行(从问题中可以看出您没有完全控制)。
(*有一些边缘情况,线程可以在一个地方挂起,然后允许其他代码在另一个地方运行[例如,当ajax调用完成并显示alert
消息时,某些浏览器会触发ajax处理程序,即使另一个函数正在等待alert
被解除阻塞],但它们是边界情况,仍然只有一个活动任务。)