JavaScript 传统 & 现代DOM加载

处理页面文档加载的时候,遇到一个难题,如果使用window.onload这种将所有内容加载后(包括DOM文档结构,外部脚本、样式,图片音乐等)这样会导致在长时间加载页面的情况下,JS程序是不可用的状态。而JS其实只需要HTML DOM文档结构构造完毕之后就可以使用,没有必要等到比如图片、音乐和外部内容加载才去执行。

传统DOM加载

window.onload = function(){
    //执行的代码..
};

浏览器加载的顺序:
1.HTML解析完毕。
2.外部脚本和样式加载完毕。
3.脚本在文档内解析并执行。
4.HTML DOM树完全构造起来。
5.图片、音乐和外部内容加载。
6.网页完成加载。

这里需要了解一个问题:
1. 步骤1-4的加载是极快的,但是第5条,根据网速和内容的多少各有快慢。
2. 因此在步骤1-4完成之后,方可执行JS内部的程序。并不需要等到加载第5条完毕之后,所以需要提供一种可以替代window.onload更快的解决方案。


现代DOM加载

非IE浏览器:

if (document.addEventListener) { 
  addEvent(document, 'DOMContentLoaded', function () {
        //执行的代码...
  });
}

PS:非IE浏览器提供了一种加载事件:DOMContentLoaded,这个事件可以在完成HTML DOM结构之后就触发。不会理会图片、音乐和外部内容等是否已经下载完毕。


IE浏览器方法一:

document.write("<script id=\"ie_onload\" defer=\"defer\" src=\"javascript:void(0)\">
<\/script>");
var script = document.getElementById("ie_onload");
script.onreadystatechange = function () {
  if (this.readyState=='complete') {
        //执行的代码...
  }
};

PS:在IE 浏览器如果网页上有<iframe>加载另一个网页,我们发现IE 浏览器还需要加载完毕iframe 所有的内容才可以执行。而非IE 浏览器的DOMContentLoaded 事件则还是DOM加载完毕后就执行了,在这里我们就发现IE 的这种方式并不完美,当然,如果页面没有iframe的话就够用了。


IE浏览器方法二:

//使用doScroll()来判断DOM 加载完毕
var timer = null;
timer = setInterval(function () {
  try {
    document.documentElement.doScroll('left');
    //执行的代码...
  } catch (ex) {};
});

PS:在IE 中,任何DOM 元素都有一个doScroll 方法,无论它们是否支持滚动条。为了判断DOM 树是否建成,我们只看看documentElement 是否完整就是,因为,它作为最外层的元素,作为DOM 树的根部而存在,如果documentElement 完整的话,就可以调用doScroll方法了。当页面一加载JS 时,我们就执行此方法,当然要如果documentElement 还不完整就会报错,我们在catch 块中重新调用它,一直到成功执行,成功执行时就可以调用fn 方法了。


现代DOM加载兼容性

function addDomLoaded(fn){
    if(document.addEventListener){ //W3C
        document.addEventListener('DOMContentLoaded',function(){
            fn();
            document.removeEventListener('DOMContentLoaded',arguments.callee,false); //arguments.callee
        },false);
    }else{
        var timer = null;
        timer = setInterval(function(){
            try{
                document.documentElement.doScroll('left');
                fn();
            }catch(ex){};
        });
    }
}
//调用
addDomLoaded(function(){
    //执行的代码...
});
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值