我检查了Dean Edward的onload
帖子,有一个问题:这种onload
附加方法有什么问题?它在哪里以及为什么会失败?什么时候使用这个简单的函数是安全的呢?
function addLoadEvent(func){
var oldonload = window.onload;
if(typeof window.onload != 'function'){
window.onload = func;
}else{
window.onload = function(){
oldonload();
func();
}
}
}
Dean的文章的重点不是关于如何挂钩window.load
事件,而是如何挂钩一个有用的事件到window.load
。window.load
发生在页面加载周期的非常非常晚的时候(在所有资源(包括所有图像)完全加载之后)。如果您的页面有任何重要的资源,并且您要等到window.load
来连接您的事件处理程序,那么您的用户可能会在您的处理程序连接之前开始做一些事情。
注意,Dean的文章写于2006年。现代的做法是简单地将脚本放在结束的</body>
标记之前。只要你的脚本是在它所引用的任何元素之后,你就可以访问这些元素。这样的话,你就可以很早就把事情联系起来了。
示例(活副本):
HTML:<p>This page has a big image on it, to help demonstrate
<code>window.load</code>'s very late arrival.
Note that this paragraph started out black, but was
turned green <em>immediately</em> on page load.
This demonstrates that the paragraph was available
to the code at the end of the page.
</p>
<img src="http://apod.nasa.gov/apod/image/1110/sh2136s_block900.jpg" style="position: absolute; top: 20em;">
JavaScript(就在</body>
结束标签之前):
(function() {
var first;
function hookLoad(handler) {
if (window.addEventListener) {
window.addEventListener("load", handler, false);
}
else if (window.attachEvent) {
window.attachEvent("onload", handler);
}
}
display("Script running at end of page; turning paragraph green.");
document.getElementsByTagName('p')[0].style.color = "green";
hookLoad(function() {
display("First load handler");
});
hookLoad(function() {
display("Second load handler");
});
function display(msg) {
var p = document.createElement('p'),
now = new Date().getTime();
msg = now + ": " + msg;
if (first) {
msg += " (delayed by " + (now - first) + "ms)";
}
else {
first = now;
}
p.innerHTML = msg;
document.body.appendChild(p);
}
})();
如果你不能这样做(把脚本放在body
元素的末尾),那么像Dean的技巧开始有用,但我强烈建议反对 DIY"DOM加载"处理;相反,应该使用良好的、维护良好的库,如jQuery、Prototype、YUI或其他几个库中的任何一个,并使用它们的"ready"事件。通过利用这些库中正在进行的工作,你可以专注于你自己的页面/应用程序。
引用:
- YUI加快网站速度的最佳实践
- Google关于DOM元素何时可访问(以及为什么他们的库没有"DOM ready"事件)
[Re window.load
特别:你不必求助于你的技巧,只需使用addEventListener
(如果浏览器支持它,除了旧的IE版本)或attachEvent
(旧的IE)。参见上面示例中的hookLoad
。