页面加载完成后执行javascript [重复]
Posted
技术标签:
【中文标题】页面加载完成后执行javascript [重复]【英文标题】:Execute javascript after page load is complete [duplicate] 【发布时间】:2015-01-13 07:05:10 【问题描述】:我有一个 html 页面,其中包含一些预渲染的内容和一些尚未渲染的内容。我想立即显示预渲染的内容,然后开始渲染其余的内容。 我没有使用 jQuery。
参见下面的 sn-p。我尝试了各种方法,包括在结束正文标记之前注入我的脚本,并提供我的脚本来填充 DOM 作为对window.onload
、document.body.onload
和document.addEventListener('DOMContentLoaded')
的回调。在任何情况下,页面都不会显示预渲染的内容,直到其余内容被渲染。
<html><head></head>
<body>
<header>What it is, my doge?</header>
<div id="main"></div>
<script>
var main = document.getElementById('main');
for (var i = 0; i < 500; i++)
main.innerText += new Date();
</script>
</body>
</html>
<html><head></head>
<body>
<header>What it is, my doge?</header>
<div id="main"></div>
<script>
var main = document.getElementById('main');
document.body.onload = function()
for (var i = 0; i < 500; i++)
main.innerText += new Date();
;
</script>
</body>
</html>
<html><head></head>
<body>
<header>What it is, my doge?</header>
<div id="main"></div>
<script>
var main = document.getElementById('main');
window.onload = function()
for (var i = 0; i < 500; i++)
main.innerText += new Date();
;
</script>
</body>
</html>
<html><head></head>
<body>
<header>What it is, my doge?</header>
<div id="main"></div>
<script>
var main = document.getElementById('main');
document.addEventListener('DOMContentLoaded', function()
for (var i = 0; i < 500; i++)
main.innerText += new Date();
);
</script>
</body>
</html>
一个有效的案例是window.setTimeout
,超时时间为0。但是,这只是将功能推迟到无事可做。这是最佳做法吗?
<html><head></head>
<body>
<header>What it is, my doge?</header>
<div id="main"></div>
<script>
var main = document.getElementById('main');
window.setTimeout(function()
for (var i = 0; i < 500; i++)
main.innerText += new Date();
, 0);
</script>
</body>
</html>
【问题讨论】:
1) 我们需要这里的代码。 2)您的描述与小提琴不符。 3) window.onload 将在所有内容加载完毕后触发。你需要做的就是把你的电话放在</body>
标签之前
小提琴正是你所描述的一个例子,它显然不起作用。
@MatthewJamesDavis 您的未渲染内容是如何渲染的?
任意。可能通过剔除或通过 DOM API 附加文档片段。
注意:setTimeout(function(), 0)
方法在 FireFox 中似乎不起作用。它需要约 50-100 毫秒的超时时间。
【参考方案1】:
就最佳实践而言,没有。就良好、常见和可接受的做法而言,有一些。你中了一个:
setTimeout(function() , 1);
在这种情况下,函数在所有其他内联处理结束后在the browser's minimum timeout period 内执行。
同样,如果您想确保您的函数在某些条件为真后不久运行,请使用间隔:
var readyCheck = setInterval(function()
if (readyCondition)
/* do stuff */
clearInterval(readyCheck);
, 1);
我一直在自己的工作中使用类似但更通用的解决方案。我在标题中定义了一个辅助函数:
var upon = function(test, fn)
if (typeof(test) == 'function' && test())
fn();
else if (typeof(test) == 'string' && window[test])
fn();
else
setTimeout(function() upon(test, fn); , 50);
; // upon()
...当依赖关系解决时,我会触发其他功能:
upon(function() return MyNS.Thingy; , function()
// stuff that depends on MyNS.Thingy
);
upon(function() return document.readyState == 'complete';, function()
// stuff that depends on a fully rendered document
);
或者,如果您想要更权威的良好实践,请遵循 Google 的示例。创建一个外部 async
脚本并将其注入到您的第一个标头 script
之前:
var s = document.createElement('script'); s.type = 'text/javascript'; s.async = true;
s.src = '/path/to/script.js';
var header_scripts = document.getElementsByTagName('script')[0];
header_scripts.parentNode.insertBefore(s, header_scripts);
Google 的解决方案理论上适用于所有浏览器(IE
如果您想要一个权威的common实践,请查看 jQuery 的onready
解决方案的来源。
【讨论】:
知道为什么谷歌建议你建议你注入它而不是包含它吗? @MatthewJamesDavis Two reasons 我知道。这里似乎只有一个相关:某些浏览器不支持async
属性。
@MatthewJamesDavis 在此处查看对async
的浏览器支持:developer.mozilla.org/en-US/docs/Web/HTML/Element/…
我会在你对未来求职者的回答中包含异步
@svidgen:我可以直接使用带有 aync 属性的标题部分中的脚本标记来代替脚本注入吗? (如下所示)<script async src="/path/to/script.js" type="text/javascript"></script>
【参考方案2】:
根据您的浏览器要求,您可以使用async
标签并在内容加载后导入您的脚本。这可能与setTimeout(func, 0)
完成相同的事情,但也许它不那么hacky。
见http://plnkr.co/edit/7DlNWNHnyX5s6UE8AFiU?p=preview
html:
...
<body>
<h1 id="main">Hello Plunker!</h1>
<script async src="script.js"></script>
</body>
...
script.js:
for(var i=0; i<500; ++i)
document.getElementById('main').innerText += new Date();
【讨论】:
它的 hacky 少了很多。 setTimeout 方法说“嘿,在你下载这个脚本时停止一切,然后完成你要做的任何事情,然后执行脚本”,其中 async 说“完成所有事情,然后在准备好时执行脚本”【参考方案3】:我以前用过这个效果:
var everythingLoaded = setInterval(function()
if (/loaded|complete/.test(document.readyState))
clearInterval(everythingLoaded);
init(); // this is the function that gets called when everything is loaded
, 10);
【讨论】:
【参考方案4】:我认为您想要做的是在标签上使用 onload 事件。 这边首先是“这是什么,我的总督?”处理 javascript 时将出现消息。
我还在循环内设置了一个超时,这样你就可以更好地看到正在添加的行。
<html>
<head>
<script>
myFunction = function()
for (var i = 1000; i > 0; i--)
setTimeout(function()
main.innerText += new Date();
, 100);
;
</script>
</head>
<body onload="myFunction()">
<header>What it is, my doge?</header>
<div id="main"></div>
</body>
</html>
【讨论】:
欣赏答案。然而,这并不像我发布的想法那样最佳,在回调之外设置一个对 window.setTimeout 的调用,超时为 0,这要快得多。以上是关于页面加载完成后执行javascript [重复]的主要内容,如果未能解决你的问题,请参考以下文章
页面用jquery的load()方法加载新页面之后怎么返回上一页
如何让js在页面加载后只执行一次,也就是再次刷新当前页,不再执行js