提问人:Robin Rodricks 提问时间:5/1/2009 最后编辑:Kamil KiełczewskiRobin Rodricks 更新时间:12/30/2022 访问量:2339797
如何让JavaScript在页面加载后执行?
How to make JavaScript execute after page load?
问:
我正在执行一个外部脚本,使用内部.<script>
<head>
现在,由于脚本在页面加载之前执行,因此我无法访问 ,等等。我想在文档“加载”后执行一些 JavaScript(HTML 完全下载并在 RAM 中)。当我的脚本执行时,是否有任何事件可以挂接到,这些事件将在页面加载时触发?<body>
答:
看看钩子或jQuery。document.onload
$(document).load(...)
评论
onload
只需定义将在加载页面后调用的内容即可。脚本中的代码比 括起来。<body onload="aFunction()">
aFunction() { }
这些解决方案将起作用:
如评论中所述,使用 defer:
<script src="deferMe.js" defer></script>
或
<body onload="script();">
或
document.onload = function ...
甚至
window.onload = function ...
请注意,最后一个选项是更好的选择,因为它不显眼并且被认为更标准。
评论
defer
</body>
您可以在正文中放置一个“onload”属性
...<body onload="myFunction()">...
或者,如果你使用的是jQuery,你可以做
$(document).ready(function(){ /*code here*/ })
or
$(window).load(function(){ /*code here*/ })
我希望它能回答你的问题。
请注意,$(window).load 将在文档呈现到您的页面上后执行。
正如 Daniel 所说,你可以使用 document.onload。
各种 javascript 框架(jQuery、Mootools 等)都使用自定义事件“domready”,我想这一定更有效。如果你正在使用 javascript 进行开发,我强烈建议你利用一个框架,它们可以大大提高你的生产力。
合理可移植的非框架方式,让您的脚本将函数设置为在加载时运行:
if(window.attachEvent) {
window.attachEvent('onload', yourFunctionName);
} else {
if(window.onload) {
var curronload = window.onload;
var newonload = function(evt) {
curronload(evt);
yourFunctionName(evt);
};
window.onload = newonload;
} else {
window.onload = yourFunctionName;
}
}
评论
使用 YUI 库(我喜欢它):
YAHOO.util.Event.onDOMReady(function(){
//your code
});
便携且美观!但是,如果您不将 YUI 用于其他东西(请参阅其文档),我会说不值得使用它。
注意:要使用此代码,您需要导入 2 个脚本
<script type="text/javascript" src="http://yui.yahooapis.com/2.7.0/build/yahoo/yahoo-min.js" ></script>
<script type="text/javascript" src="http://yui.yahooapis.com/2.7.0/build/event/event-min.js" ></script>
下面是一个基于页面加载后延迟 js 加载的脚本,
<script type="text/javascript">
function downloadJSAtOnload() {
var element = document.createElement("script");
element.src = "deferredfunctions.js";
document.body.appendChild(element);
}
if (window.addEventListener)
window.addEventListener("load", downloadJSAtOnload, false);
else if (window.attachEvent)
window.attachEvent("onload", downloadJSAtOnload);
else window.onload = downloadJSAtOnload;
</script>
我该把它放在哪里?
将代码粘贴到 HTML 中标记的前面(靠近 HTML 文件的底部)。
</body>
它有什么作用?
这段代码说等待整个文档加载完毕,然后加载 外部文件。
deferredfunctions.js
下面是上述代码的示例 - JS 的延迟渲染
我写这篇文章是基于 javascript pagespeed google 概念的延迟加载,也来源于这篇文章延迟加载 javascript
评论
chaos
如果您使用的是 jQuery,
$(function() {...});
相当于
$(document).ready(function () { })
或其他简手:
$().ready(function () { })
请参阅 JQuery $function() 在什么事件上触发?和 https://api.jquery.com/ready/
工作小提琴<body onload="myFunction()">
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function myFunction(){
alert("Page is loaded");
}
</script>
</head>
<body onload="myFunction()">
<h1>Hello World!</h1>
</body>
</html>
<body onload="myFunction()">
此代码运行良好。
但是方法有各种依赖关系。所以它可能不会一直有效。window.onload
我发现有时在更复杂的页面上,并非所有元素在触发 window.onload 时都已加载。如果是这种情况,请在函数延迟片刻之前添加 setTimeout。它并不优雅,但它是一个简单的技巧,渲染得很好。
window.onload = function(){ doSomethingCool(); };
成为。。。
window.onload = function(){ setTimeout( function(){ doSomethingCool(); }, 1000); };
如果脚本加载到文档中,则可以在脚本标记中使用该属性。<head>
defer
例:
<script src="demo_defer.js" defer></script>
从 https://developer.mozilla.org:
推迟
此 Boolean 属性设置为向浏览器指示脚本 在解析文档之后执行,但在解析文档之前执行 触发 DOMContentLoaded。
如果 src 属性不存在(即对于内联脚本),在这种情况下,它会 没有效果。
要实现动态插入脚本的类似效果,请使用 async=false 代替。具有 defer 属性的脚本将在 它们在文档中出现的顺序。
评论
document.onreadystatechange = function(){
if(document.readyState === 'complete'){
/*code here*/
}
}
看这里:http://msdn.microsoft.com/en-us/library/ie/ms536957(v=vs.85).aspx
评论
<script type="text/javascript">
function downloadJSAtOnload() {
var element = document.createElement("script");
element.src = "defer.js";
document.body.appendChild(element);
}
if (window.addEventListener)
window.addEventListener("load", downloadJSAtOnload, false);
else if (window.attachEvent)
window.attachEvent("onload", downloadJSAtOnload);
else window.onload = downloadJSAtOnload;
</script>
http://www.feedthebot.com/pagespeed/defer-loading-javascript.html
我建议将属性用于脚本标签,帮助您在页面加载后加载外部脚本asnyc
<script type="text/javascript" src="a.js" async></script>
<script type="text/javascript" src="b.js" async></script>
评论
defer
<script type="text/javascript">
$(window).bind("load", function() {
// your javascript event here
});
</script>
评论
有一个非常好的文档关于如何检测文档是否已使用 Javascript 或 Jquery 加载。
使用原生 Javascript 可以实现这一点
if (document.readyState === "complete") {
init();
}
这也可以在间隔内完成
var interval = setInterval(function() {
if(document.readyState === 'complete') {
clearInterval(interval);
init();
}
}, 100);
switch (document.readyState) {
case "loading":
// The document is still loading.
break;
case "interactive":
// The document has finished loading. We can now access the DOM elements.
var span = document.createElement("span");
span.textContent = "A <span> element.";
document.body.appendChild(span);
break;
case "complete":
// The page is fully loaded.
console.log("Page is loaded completely");
break;
}
使用 Jquery 仅检查 DOM 是否准备就绪
// A $( document ).ready() block.
$( document ).ready(function() {
console.log( "ready!" );
});
要检查是否加载了所有资源,请使用 window.load
$( window ).load(function() {
console.log( "window loaded" );
});
在适当的时候触发脚本
关于如何在打算加载/执行脚本的那一刻加载/运行脚本的快速概述。使用“defer”
<script src="script.js" defer></script>
使用 defer 将在 domInteractive (document.readyState = “interactive”) 之后和触发 “DOMContentLoaded” 事件之前触发。如果需要在加载所有资源(图像、脚本)后执行脚本,请使用 “load” 事件或以 document.readyState 状态之一为目标。请继续阅读,了解有关这些事件/状态的更多信息,以及与脚本获取和执行计时相对应的 async 和 defer 属性。
此 Boolean 属性设置为向浏览器指示脚本 在解析文档之后执行,但在解析文档之前执行 触发 DOMContentLoaded。
具有 defer 属性的脚本将阻止 DOMContentLoaded 事件从触发到脚本加载并完成计算。
资源: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attributes
* 有关羽毛说明,请参阅底部的图片。
事件侦听器 - 请记住,加载页面时有多个事件:
“DOMContentLoaded”
当初始 HTML 文档完全加载和解析时,将触发此事件,而无需等待样式表、图像和子帧完成加载。在此阶段,您可以根据用户设备或带宽速度以编程方式优化图像和 CSS 的加载。
加载 DOM 后执行(在图像和 CSS 之前):
document.addEventListener("DOMContentLoaded", function(){
//....
});
注意:同步 JavaScript 会暂停 DOM 的解析。 如果您希望在用户请求页面后尽快解析 DOM,您可以将 JavaScript 异步化并优化样式表的加载
“加载”
一个非常不同的事件 **load** 应该只用于检测 *完全加载的页面*。在 DOMContentLoaded 更合适的地方使用 load 是一个非常普遍的错误,因此请谨慎。在加载并解析所有内容后执行:
document.addEventListener("load", function(){
// ....
});
MDN 资源:https://developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded https://developer.mozilla.org/en-US/docs/Web/Events/load
MDN 所有事件列表:
https://developer.mozilla.org/en-US/docs/Web/Events
具有 readyStates 的事件侦听器 - 替代解决方案 (readystatechange):
您还可以跟踪 document.readystatechange 状态以触发脚本执行。// Place in header (do not use async or defer)
document.addEventListener('readystatechange', event => {
switch (document.readyState) {
case "loading":
console.log("document.readyState: ", document.readyState,
`- The document is still loading.`
);
break;
case "interactive":
console.log("document.readyState: ", document.readyState,
`- The document has finished loading DOM. `,
`- "DOMContentLoaded" event`
);
break;
case "complete":
console.log("document.readyState: ", document.readyState,
`- The page DOM with Sub-resources are now fully loaded. `,
`- "load" event`
);
break;
}
});
MDN 资源: https://developer.mozilla.org/en-US/docs/Web/API/Document/readyState
将脚本放在哪里(带 & 不带异步/延迟)?
了解脚本的放置位置以及它在 HTML 中的位置以及 defer 和 async 等参数会影响脚本获取、执行和 HTML 阻止也非常重要。* 在下面的图片中,黄色标签“Ready”表示结束加载 HTML DOM 的时刻。然后它触发: document.readyState = “interactive” >>> DOMContentLoaded 事件>>>延迟脚本(它是连续的);
如果您的脚本使用 async 或 defer,请阅读以下内容: https://flaviocopes.com/javascript-async-defer/
如果以上所有几点都还为时过早......
如果您需要在其他脚本运行后运行脚本,包括那些计划在最后运行的脚本(例如,那些为“加载”事件计划运行的脚本),该怎么办?请参阅在所有 window.onload 脚本完成后运行 JavaScript?
如果您需要确保脚本在其他脚本之后运行,而不管它何时运行,该怎么办?上述问题的答案也涵盖了这一点。
评论
window.onload = ...
window.onload
document.addEventListener("DOMContentLoaded", ...
window.addEventListener("load", ...
window.onload
window.addEventListener("load", ...
document.addEventListener("DOMContentLoaded", ...
将此代码与jQuery库一起使用,这将完全正常工作。
$(window).bind("load", function() {
// your javascript event
});
评论
$(window).on("load", function(){ ... });
.ready() 最适合我。
$(document).ready(function(){ ... });
.load() 可以工作,但它不会等到页面加载。
jQuery(window).load(function () { ... });
对我不起作用,破坏了下一个内联脚本。我还使用 jQuery 3.2.1 以及其他一些 jQuery 分支。
为了隐藏我的网站加载叠加层,我使用以下内容:
<script>
$(window).on("load", function(){
$('.loading-page').delay(3000).fadeOut(250);
});
</script>
JavaScript的
document.addEventListener('readystatechange', event => {
// When HTML/DOM elements are ready:
if (event.target.readyState === "interactive") { //does same as: ..addEventListener("DOMContentLoaded"..
alert("hi 1");
}
// When window loaded ( external resources are loaded too- `css`,`src`, etc...)
if (event.target.readyState === "complete") {
alert("hi 2");
}
});
jQuery也一样:
$(document).ready(function() { //same as: $(function() {
alert("hi 1");
});
$(window).load(function() {
alert("hi 2");
});
注意: - 不要使用以下标记(因为它会覆盖其他同类声明):
document.onreadystatechange = ...
比较
在下面的片段中,我收集了选择的方法并显示了它们的顺序。言论
- 任何现代浏览器都不支持 (X) (事件从不触发
document.onload
) - 如果同时使用 (F) 和 (E),则只会执行第一个(因为它覆盖了第二个)
<body onload="bodyOnLoad()">
window.onload
- (F) 中给出的事件处理程序由附加函数包装
<body onload="...">
onload
document.onreadystatechange
(D) 不覆盖 (C) 可能 cecasue 方法与队列无关(允许添加多个侦听器)。在执行这两个处理程序之间可能没有任何反应。document .addEventListener('readystatechange'...)
onXYZevent-like
addEventListener
- 所有脚本都在控制台中写入其时间戳 - 但脚本也可以在正文中写入其时间戳(在脚本执行后单击“整页”链接以查看它)。
div
- 解决方案 (C,D) 由浏览器执行多次,但针对不同的文档状态:
readystatechange
- loading - 文档正在加载(代码段中未触发)
- 交互式 - 文档被解析,触发之前
DOMContentLoaded
- 完成 - 文档和资源已加载,在之前触发
body/window onload
<html>
<head>
<script>
// solution A
console.log(`[timestamp: ${Date.now()}] A: Head script`);
// solution B
document.addEventListener("DOMContentLoaded", () => {
print(`[timestamp: ${Date.now()}] B: DOMContentLoaded`);
});
// solution C
document.addEventListener('readystatechange', () => {
print(`[timestamp: ${Date.now()}] C: ReadyState: ${document.readyState}`);
});
// solution D
document.onreadystatechange = s=> {print(`[timestamp: ${Date.now()}] D: document.onreadystatechange ReadyState: ${document.readyState}`)};
// solution E (never executed)
window.onload = () => {
print(`E: <body onload="..."> override this handler`);
};
// solution F
function bodyOnLoad() {
print(`[timestamp: ${Date.now()}] F: <body onload='...'>`);
infoAboutOnLoad(); // additional info
}
// solution X
document.onload = () => {print(`document.onload is never fired`)};
// HELPERS
function print(txt) {
console.log(txt);
if(mydiv) mydiv.innerHTML += txt.replace('<','<').replace('>','>') + '<br>';
}
function infoAboutOnLoad() {
console.log("window.onload (after override):", (''+document.body.onload).replace(/\s+/g,' '));
console.log(`body.onload==window.onload --> ${document.body.onload==window.onload}`);
}
console.log("window.onload (before override):", (''+document.body.onload).replace(/\s+/g,' '));
</script>
</head>
<body onload="bodyOnLoad()">
<div id="mydiv"></div>
<!-- this script must te at the bottom of <body> -->
<script>
// solution G
print(`[timestamp: ${Date.now()}] G: <body> bottom script`);
</script>
</body>
</html>
我可以通过此代码捕获页面加载
<script>
console.log("logger saber");
window.onload = (event) => {
console.log('page is fully loaded');
document.getElementById("tafahomNameId_78ec7c44-beab-40de-9326-095f474519f4_$LookupField").value = 1;;
};
</script>
您可以在特定脚本文件上编写函数,并使用 onload 属性将其调用到 body 元素中。
示例:
<script>
afterPageLoad() {
//your code here
}
</script>
现在使用 script 标签将脚本调用到 html 页面中:
<script src="afterload.js"></script>
进入你的身体元素;添加 onload 属性,如下所示:
<body onload="afterPageLoad();">
评论