jQuery Ready 与 Window onload 的区别(转)

“咱们都知道,不少时候,在页面加载完后都须要作一些相应的初始化动做.例如,运行某些js特效,设置表单等等.怎么知道页面加载完了呢?
一 般状况下都是设置body标签的onload监听window的load事件.但load事件是要在页面的元素所有加载完了才触发的,若是页面上图片较多 或图片太大,就会致使初始化的代码未被执行的时候用户就作了其它操做了. Jquery库提供了一个很是方便好用的函数( $(selector).ready()),让咱们能够在页面的dom加载完后就能够作相应的操做(固然,这还得看用户浏览器的支持).,而不用等待所有 元素加载完成.例如:
javascript

1 $(document).ready(function (){ alert('use in page script tag') }); 2 $(document).ready(function (){ alert('use in import js file') });


如今让咱们来研究一下这个函数的实现.
原理:
在jquery脚本加载的时候,会设置一个isReady的标记,监听 DOMContentLoaded事件(这个不是什么浏览器都有的,不一样浏览器,jquery运做方式不同).固然遇到调用ready函数的时候,若是 isReady未被设置,那就是说页面未加载完,就会把要执行的函数用一个数组缓存起来,当页面加载完后,再把缓存的函数一一执行.
Jquery中的详细代码分析: css

复制代码
 1 ready: function(fn) {  2 // 绑定监听器  3 bindReady();  4 // 若是 DOM 加载完成  5 if ( jQuery.isReady )  6 // 立刻运行此函数  7 fn.call( document, jQuery );  8 // 不然保存起来  9 else 10 // 把函数加入缓存数组中 11 jQuery.readyList.push( function() { return fn.call(this, jQuery); } ); 12 return this; 13 } 
复制代码

让咱们看看jquery若是实现不一样浏览器dom加载完成的通知 bindReady()函数:java

复制代码
 1 var readyBound = false;  2 function bindReady(){  3 if ( readyBound ) return;  4 readyBound = true;  5  6 // Mozilla,opera,webkitnightlies支持DOMContentLoaded事件  7 if ( document.addEventListener && !jQuery.browser.opera)  8 // 直接使用事件回调便可  9 document.addEventListener( "DOMContentLoaded", jQuery.ready, false ); 10 11 // 若是是ie而且不是嵌在frame中 12 // 就须要不断地检查文档是否加载完 13 if ( jQuery.browser.msie && window == top ) (function(){ 14 if (jQuery.isReady) return; 15 try { 16 // 这个地方标记一下,在后面解析(1) 17 document.documentElement.doScroll("left"); 18 } catch( error ) { 19 //// 这个地方标记一下,在后面解析(2) 20 setTimeout( arguments.callee, 0 ); 21 return; 22 } 23 // and execute any waiting functions 24 jQuery.ready(); 25 })(); 26 27 if ( jQuery.browser.opera ) 28 document.addEventListener( "DOMContentLoaded", function () { 29 if (jQuery.isReady) return; 30 for (var i = 0; i < document.styleSheets.length; i++) // 标记(3) 31 if (document.styleSheets[i].disabled) { 32 setTimeout( arguments.callee, 0 ); 33 return; 34 } 35 // and execute any waiting functions 36 jQuery.ready(); 37 }, false); 38 39 if ( jQuery.browser.safari ) { 40 var numStyles; 41 (function(){ 42 if (jQuery.isReady) return; 43 if ( document.readyState != "loaded" && document.readyState != "complete" ) { // 标记(4) 44 setTimeout( arguments.callee, 0 ); 45 return; 46 } 47 if ( numStyles === undefined ) 48 numStyles = jQuery("style, link[rel=stylesheet]").length; 49 if ( document.styleSheets.length != numStyles ) { // 标记(5) 50 setTimeout( arguments.callee, 0 ); 51 return; 52 } 53 // and execute any waiting functions 54 jQuery.ready(); 55 })(); 56 } 57 58 // A fallback to window.onload, that will always work 59 jQuery.event.add( window, "load", jQuery.ready ); // 标记(6) 60 } 61 } 
复制代码

1):这个主要是测出ie下的dom ready,原理在这里http://javascript.nwbox.com/IEContentLoaded/,利用在ie下.当dom未完成解析 时,调用document的document.documentElement.doScroll(”left”)会出错这个小技巧即可得知dom有没有 ready了.
(2):setTimeout( arguments.callee, 0 )这句是表示延迟0秒调用,实际上它不会立刻就调用,而是会尽量快地调用,它告诉浏览器为当前任何挂起的事件运行完事件句柄而且完成了文档当前状态的更 新后才调用. Arguments.callee便是外层的匿名函数,参数的调用者
(3):这个地方你也许以为奇怪,为何不在mozilla那里一块儿处理呢? 缘由就是opera的DOMContentLoaded事件发生后,其css样式是还没彻底可用的,因此要特殊处理,就是判断每一个css的tag都是否是enable了.
(4),(5):safari中document.readyState的状态为loaded或complete时,css文件引入还未能肯定是否是解析完了的,因此要经过判断其css文件数目
(6):最后,若是上面的hack都不支持的话…就用最保险的load事件,保证能执行到初始化代码. jquery

相关文章
相关标签/搜索