jquery ready函数源代码研究

萌萌哒的女疯纸

萌萌哒的女疯纸

2016-02-19 14:34

下面图老师小编要向大家介绍下jquery ready函数源代码研究,看起来复杂实则是简单的,掌握好技巧就OK,喜欢就赶紧收藏起来吧!
一般情况下都是设置body标签的onload监听window的load事件.但load事件是要在页面的元素全部加载完了才触发的,如果页面上图片较多或图片太大,就会导致初始化的代码未被执行的时候用户就做了其它操作了. Jquery库提供了一个非常方便好用的函数( $(selector).ready()),让我们可以在页面的dom加载完后就可以做相应的操作(当然,这还得看用户浏览器的支持).,而不用等待全部元素加载完成.例如:
$(document).ready(function (){ alert('use in page script tag') });
$(document).ready(function (){ alert('use in import js file') });
现在让我们来研究一下这个函数的实现.
原理:
在jquery脚本加载的时候,会设置一个isReady的标记,监听DOMContentLoaded事件(这个不是什么浏览器都有的,不同浏览器,jquery运作方式不一样).当然遇到调用ready函数的时候,如果isReady未被设置,那就是说页面未加载完,就会把要执行的函数用一个数组缓存起来,当页面加载完后,再把缓存的函数一一执行.
Jquery中的详细代码分析:


代码如下:
ready: function(fn) {
// 绑定监听器
bindReady();
// 如果 DOM 加载完成
if ( jQuery.isReady )
// 马上运行此函数
fn.call( document, jQuery );
// 否则保存起来
else
// 把函数加入缓存数组中
jQuery.readyList.push( function() { return fn.call(this, jQuery); } );
return this;
}


让我们看看jquery如果实现不同浏览器dom加载完成的通知 bindReady()函数:

代码如下:
var readyBound = false;
function bindReady(){
if ( readyBound ) return;
readyBound = true;

// Mozilla,opera,webkitnightlies支持DOMContentLoaded事件
if ( document.addEventListener && !jQuery.browser.opera)
// 直接使用事件回调即可
document.addEventListener( "DOMContentLoaded", jQuery.ready, false );

// 如果是ie并且不是嵌在frame中
// 就需要不断地检查文档是否加载完
if ( jQuery.browser.msie && window == top ) (function(){
if (jQuery.isReady) return;
try {
// 这个地方标记一下,在后面解析(1)
document.documentElement.doScroll("left");
} catch( error ) {
//// 这个地方标记一下,在后面解析(2)
setTimeout( arguments.callee, 0 );
return;
}
// and execute any waiting functions
jQuery.ready();
})();

if ( jQuery.browser.opera )
document.addEventListener( "DOMContentLoaded", function () {
if (jQuery.isReady) return;
for (var i = 0; i document.styleSheets.length; i++) // 标记(3)
if (document.styleSheets[i].disabled) {
setTimeout( arguments.callee, 0 );
return;
}
// and execute any waiting functions
jQuery.ready();
}, false);

if ( jQuery.browser.safari ) {
var numStyles;
(function(){
if (jQuery.isReady) return;
if ( document.readyState != "loaded" && document.readyState != "complete" ) { // 标记(4)
setTimeout( arguments.callee, 0 );
return;
}
if ( numStyles === undefined )
numStyles = jQuery("style, link[rel=stylesheet]").length;
if ( document.styleSheets.length != numStyles ) { // 标记(5)
setTimeout( arguments.callee, 0 );
return;
}
// and execute any waiting functions
jQuery.ready();
})();
}

// A fallback to window.onload, that will always work
jQuery.event.add( window, "load", jQuery.ready ); // 标记(6)
}
}


(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事件,保证能执行到初始化代码.
展开更多 50%)
分享

猜你喜欢

jquery ready函数源代码研究

Web开发
jquery ready函数源代码研究

Jive源代码研究

编程语言 网络编程
Jive源代码研究

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

JQuery下关于$.Ready()的分析

Web开发
JQuery下关于$.Ready()的分析

jQuery 源代码显示控件 (Ajax加载方式).

Web开发
jQuery 源代码显示控件 (Ajax加载方式).

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

jquery ready()的几种实现方法小结

Web开发
jquery ready()的几种实现方法小结

AJAX 请求 源代码

Web开发
AJAX 请求 源代码

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

纯JS五子棋(各浏览器兼容)

纯JS五子棋(各浏览器兼容)

Windows 8计算机管理功能怎么用?

Windows 8计算机管理功能怎么用?
下拉加载更多内容 ↓