jquery之 domready分析(转载)

其他JS框架的domrady实现

http://www.jb51.net/article/26251.htm

  1     Domready是每个lib都要实现的函数,因为dom还没有完全ready,那么对于对于dom元素的操作可能出错,因为dom树中可能还没有Load这个元素。为了保障不出现这样的错误,就出现地domready。对于每种浏览器Domready都有着自己不同的判断。
  2 Jquery的domready的实现和其它的lib的实现没有什么区别。
  3     //dom ready时执行 fn
  4     ready : function(fn) {            
  5             bindReady();//注册监听            
  6             if (jQuery.isReady)//ready就运行                
  7                 fn.call(document, jQuery);            
  8             else
  9                 // 增加这个函数到queue中。可见支持无数的ready的调用。
 10                 jQuery.readyList.push(function() {
 11                     return fn.call(this, jQuery);
 12                 });
 13             return this;
 14         }
 15 我们通过$(fn)的方法就是在调用这个方法。它首先通过bindReady()来注册监听dom是否已经loaded。如果已经loaded就运行fn。如果没有就把fn存放在readyList中。对于多个$(fn),把它们各自的fn参数保存在公共的jQuery. readyList的公共集合中。待到dom loaed之后统一运行。对于dom 已经loaded,就可以分别去运行fn。
 16 var readyBound = false;
 17 
 18 function bindReady() {
 19     if (readyBound)
 20         return;
 21     readyBound = true;
 22 
 23     // Mozilla, Opera, webkit nightlies 支持DOMContentLoaded事件    
 24 if (document.addEventListener && !jQuery.browser.opera)
 25         //当DOMContentLoaded事件触发时就运行jQuery.ready
 26 document.addEventListener("DOMContentLoaded", jQuery.ready, false);
 27 
 28     //IE或不是frame的window
 29     if (jQuery.browser.msie && window == top)
 30         (function() {
 31             if (jQuery.isReady)
 32                 return;
 33             try {
 34                 // 在ondocumentready之前,一直都会抛出异常                
 35                 // http://javascript.nwbox.com/IEContentLoaded/
 36                 document.documentElement.doScroll("left");
 37             } catch (error) {
 38                 //一直运行bindReady()(=arguments.callee)
 39                 setTimeout(arguments.callee, 0);
 40                 return;
 41             }            
 42             jQuery.ready();//documentready就运行jQuery.ready
 43         })();
 44 
 45     if (jQuery.browser.opera)
 46         document.addEventListener("DOMContentLoaded", function() {
 47             if (jQuery.isReady)
 48                 return;
 49                 //只有styleSheets完全enable时,才是完全的load,其实还有pic
 50         for (var i = 0;i < document.styleSheets.length; i++)
 51           if (document.styleSheets[i].disabled) {//通过styleSheets来判断
 52                     setTimeout(arguments.callee, 0);
 53                     return;
 54                 }            
 55                 jQuery.ready();
 56             }, false);
 57 
 58     if (jQuery.browser.safari) {
 59         var numStyles;
 60         (function() {
 61             if (jQuery.isReady)
 62                 return;
 63                 //首先得得到readyState=loaded或=complete
 64             if (document.readyState != "loaded"
 65                     && document.readyState != "complete") {
 66                 setTimeout(arguments.callee, 0);
 67                 return;
 68             }
 69             //取得style的length,比较它们之间的长度,看看是不是完成loaded
 70             if (numStyles === undefined)
 71                 numStyles = jQuery("style, 
 72 link[rel=stylesheet]").length;
 73             if (document.styleSheets.length != numStyles) {
 74                 setTimeout(arguments.callee, 0);
 75                 return;
 76             }            
 77             jQuery.ready();
 78         })();
 79     }
 80 
 81     //最后只能依赖于window.load.
 82     jQuery.event.add(window, "load", jQuery.ready);
 83 }
 84 这段代码看起来很多,其实就是采用setTimeout(arguments.callee, 0);反复来运行bindReady。如果其得到dom ready的条件满足的话,就执行jQuery.ready()来执行通过$(fn)注册的fn函数。对于每种浏览器,这个满足的条件是不一样。上面的代码就是针对于几种常用的浏览器分别做了各自的处理。
 85 isReady : false,
 86     readyList : [],
 87     // Handle when the DOM is ready
 88         ready : function() {            
 89             if (!jQuery.isReady) {        
 90                 jQuery.isReady = true;                
 91                 if (jQuery.readyList) {                    
 92                     jQuery.each(jQuery.readyList, function() {
 93                         this.call(document);
 94                     });                
 95                     jQuery.readyList = null;
 96                 }                
 97                 jQuery(document).triggerHandler("ready");
 98             }
 99         }
100     });
101 当运行到jQuery.ready()的时候就说明dom已经完全的Loaded,那么现在就应该执行保存在jQuery.readyList中的fn。jQuery.ready()就是完成这个工作。
posted @ 2012-11-06 13:52  draem0507  阅读(1091)  评论(0编辑  收藏  举报
View Code