原生JS实现DOM加载完成马上执行JS代码

用原生JS我们经常使用window.onload事件来加载页面。但是window.onload是在页面元素都加载完毕后才执行,如果页面内有大的图片的话,会在页面展现后好久时间后才执行。所以有时我们需要在DOM载入时马上执行一些函数。jQuery提供了document.ready方法用来代替window.onload。但又不愿意仅为了这一个需求而引入整个JQuery库,于是就把jQuery的方法提取出来,单独使用了。

如果只需要对DOM进行操作,那么这时就没必要等到页面全部加载了。Firefox有DOMContentLoaded事件可以轻松解决,可惜的就是IE没有。

MSDN关于JSCRIPT的一个方法有段不起眼的话,当页面DOM未加载完成时,调用doScroll方法时,会产生异常。那么我们反过来用,如果不异常,那么就是页面DOM加载完毕了。所以 对于Mozilla & Opera 浏览器,在dom树载入后有现成的 DOMContentLoaded 事件。对于Safari 浏览器,有document.onreadystatechange事件,当该触发时,如果 document.readyState=complete时,可视为dom树已经载入。

对于ie,当在iframe内时,同样有document.onreadystatechange事件,对于ie在非iframe内时,只有不断地通过能否执行doScroll判断dom是否加载完毕。

在本例中每间隔5毫秒尝试去执行 document.documentElement.doScroll(‘left’)。在ie8下,貌视非iframe窗口也会有 document.onreadystatechange事件,另外也可以在构建自己的框架时使用此函数。

(function(){
     var isReady=false; //判断onDOMReady方法是否已经被执行过
     var readyList= [];//把需要执行的方法先暂存在这个数组里
     var timer;//定时器句柄
 
     ready=function(fn)
     {
         if (isReady )
             fn.call( document);
         else
             readyList.push( function() { return fn.call(this);});
         return this;
     }
 
     var onDOMReady=function(){
         for(var i=0;i< readyList.length;i++)
         {
             readyList[i].apply(document);
         }
         readyList = null;
     }
 
     var bindReady = function(evt)
     {
         if(isReady) return;
         isReady=true;
         onDOMReady.call(window);
         if(document.removeEventListener)
         {
             document.removeEventListener("DOMContentLoaded", bindReady, false);
         }
         else if(document.attachEvent)
         {
             document.detachEvent("onreadystatechange", bindReady);
             if(window == window.top){
                 clearInterval(timer);//事件发生后清除定时器
                 timer = null;
             }
         }
     };
 
     if(document.addEventListener){
         document.addEventListener("DOMContentLoaded", bindReady, false);
     }
     else if(document.attachEvent)//非最顶级父窗口

     {
         document.attachEvent("onreadystatechange", function(){
             if((/loaded|complete/).test(document.readyState))
             bindReady();
         });
 
     if(window == window.top)//在应用有frameset或者iframe的页面时,parent是父窗口,top是最顶级父窗口(有的窗口中套了好几层frameset或者iframe)
     {
         timer = setInterval(function(){
             try
             {
                 isReady||document.documentElement.doScroll('left');//在IE下用能否执行doScroll判断 dom是否加载完毕
             }
             catch(e)
             {
                 return;
             }
             bindReady();
         },5);
     }
     }
 })();

下面是使用方法:
 ready(dosomething);//dosomething为已存在的函数
 //也可以通过闭包来使用
 ready(function(){
     //这里是逻辑代码
 });

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值