10
7
2011
0

document ready实现

转自:document ready实现

很多时候大家做前端时,需要在DOM树载入时马上执行一些函数,也就是实现document ready,而不是实现window.onload,比如对导航条进行初始化。但又不愿意仅为了这一个需求而引入整个jQuery库,于是就把 jQuery的ready方法提取出来,单独使用了。

代码如下:
(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){
                     timer = setInterval(function(){
                            try{
                                   isReady||document.documentElement.doScroll('left');//在IE下用能否执行doScroll判断dom是否加载完毕
                            }catch(e){
                                   return;
                            }
                            bindReady();
                     },5);
              }
       }
})();

使用方式类下:

ready(navInit);//navInit为已存在的函数

ready(function(){
       if(agt.toLowerCase().indexOf("msie 6") != -1)
              navInitForIE6();//如果浏览器是IE6,则执行navInitForIE6函数来初始化下拉菜单
});

说明:

当我们想在页面加载之后执行某个函数,肯定会想到onload了,但onload在浏览器看来,就是页面上的东西(img,iframe等资源)全部都加载完毕后才能发生,如果页面内有大的图片的话,会在页面展现后好久时间后才执行。

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

关于JSCRIPT的一个方法有段不起眼的话,当页面DOM未加载完成时,调用doScroll方法时,会产生异常。那么我们反过来用,如果不异 常,那么就是页面DOM加载完毕了!这个函数是Diego Perini在07年就发布了这个名为IEContentLoaded的方法,而且获得了广泛认同,以至于现在许多开源框架都是借鉴这种方法,譬如 JQuery中的ready,在注释里有明确说明是有借鉴Diego Perini的IEContentLoaded方法。所以,对于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事件

 

Category: Web摘记 | Tags: javascript jquery | Read Count: 1551

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter

Host by is-Programmer.com | Power by Chito 1.3.3 beta | Theme: Aeros 2.0 by TheBuckmaker.com