跨浏览器附加body onload(方法比较)

JS: Attach body onload cross browser (methods comparison)

本文关键字:方法 比较 onload body 浏览器      更新时间:2023-09-26

我检查了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.loadwindow.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