在正常情况下:

  1. window.onload 事件在所有页面元素(包括图片,脚本等)都下载完毕后才会触发。
  2. 除了 IE,其它浏览器支持 DOMContentLoaded 事件。当 DOM 内容下载完毕,就会立刻触发。
  3. 事件处理器必须在事件触发前注册才有效,否则不会被执行。例子:在 window 已经 load 完成后,再给 window.onload 注册的处理器不会被执行。
  4. 针对 IE,有各种模拟 DOMContentLoaded 事件的办法。目前被广泛采纳的方案是判断 document 是否可以滚动(doScroll)。一旦可以滚动,就意味着 DOM Content 已经加载完毕。

下面说两个陷阱

  1. 在 setTimeout 里给 window.onload 添加处理器。这是不可靠的,无法保证添加的处理器一定会执行。是否执行取决于 setTimeout 的延时和页面内容的加载时间。比如:
    // Test 1. 在 onload 后添加 onload handler
    setTimeout(function() {
        onLoad(function() {
            alert('Test 1: window loaded.'); // 不一定执行
        });
    }, 20);
    
  2. 在动态加载的 script 的 onload 事件里,给 window.DOMContentLoaded 添加处理器。这更不可靠,除了 IE,其它浏览器下根本不会执行。比如:
    // Test 2. 测试动态添加 script
    getScript('http://jqueryjs.googlecode.com/files/jquery-1.3.2.min.js', function() {
       alert('Test 2: jQuery loaded.');
        onReady(function() { alert('Test 2: content loaded.'); }); // 不可靠
    });
    

测试页面:load_test.html

最后提一点:从上面的测试页面中可以看出,IE 下模拟 DOMContentLoaded 事件仅仅是模拟,和其它浏览器依旧存在本质上的差异。在 IE 真正原生支持 DOMContentLoaded 前,疯狂使用$(document).ready(...), YAHOO.util.Event.onDOMReady(...)等方法时,依旧需要谨慎,要留意陷阱。