jQuery Ready 与 Window onload 的区别(转)

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

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中的详细代码分析:

复制代码
 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()函数:

复制代码
 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事件,保证能执行到初始化代码.

转载于:https://www.cnblogs.com/wufengtinghai/p/4345603.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值