`
jljlpch
  • 浏览: 319496 次
  • 性别: Icon_minigender_1
  • 来自: 南昌
社区版块
存档分类
最新评论

jquery event domready

阅读更多
6.3 domReady的处理
                             prk/彭仁夔    08-08-26
	Domready是每个lib都要实现的函数,因为dom还没有完全ready,那么对于对于dom元素的操作可能出错,因为dom树中可能还没有Load这个元素。为了保障不出现这样的错误,就出现地domready。对于每种浏览器Domready都有着自己不同的判断。
Jquery的domready的实现和其它的lib的实现没有什么区别。
	//dom ready时执行 fn
	ready : function(fn) {			
			bindReady();//注册监听			
			if (jQuery.isReady)//ready就运行				
				fn.call(document, jQuery);			
			else
				// 增加这个函数到queue中。可见支持无数的ready的调用。
				jQuery.readyList.push(function() {
					return fn.call(this, jQuery);
				});
			return this;
		}
我们通过$(fn)的方法就是在调用这个方法。它首先通过bindReady()来注册监听dom是否已经loaded。如果已经loaded就运行fn。如果没有就把fn存放在readyList中。对于多个$(fn),把它们各自的fn参数保存在公共的jQuery. readyList的公共集合中。待到dom loaed之后统一运行。对于dom 已经loaded,就可以分别去运行fn。
var readyBound = false;

function bindReady() {
	if (readyBound)
		return;
	readyBound = true;

	// Mozilla, Opera, webkit nightlies 支持DOMContentLoaded事件	
if (document.addEventListener && !jQuery.browser.opera)
		//当DOMContentLoaded事件触发时就运行jQuery.ready
document.addEventListener("DOMContentLoaded", jQuery.ready, false);

	//IE或不是frame的window
	if (jQuery.browser.msie && window == top)
		(function() {
			if (jQuery.isReady)
				return;
			try {
				// 在ondocumentready之前,一直都会抛出异常				
				// http://javascript.nwbox.com/IEContentLoaded/
				document.documentElement.doScroll("left");
			} catch (error) {
				//一直运行bindReady()(=arguments.callee)
				setTimeout(arguments.callee, 0);
				return;
			}			
			jQuery.ready();//documentready就运行jQuery.ready
		})();

	if (jQuery.browser.opera)
		document.addEventListener("DOMContentLoaded", function() {
			if (jQuery.isReady)
				return;
				//只有styleSheets完全enable时,才是完全的load,其实还有pic
		for (var i = 0;i < document.styleSheets.length; i++)
		  if (document.styleSheets[i].disabled) {//通过styleSheets来判断
					setTimeout(arguments.callee, 0);
					return;
				}			
				jQuery.ready();
			}, false);

	if (jQuery.browser.safari) {
		var numStyles;
		(function() {
			if (jQuery.isReady)
				return;
				//首先得得到readyState=loaded或=complete
			if (document.readyState != "loaded"
					&& document.readyState != "complete") {
				setTimeout(arguments.callee, 0);
				return;
			}
			//取得style的length,比较它们之间的长度,看看是不是完成loaded
			if (numStyles === undefined)
				numStyles = jQuery("style, 
link[rel=stylesheet]").length;
			if (document.styleSheets.length != numStyles) {
				setTimeout(arguments.callee, 0);
				return;
			}			
			jQuery.ready();
		})();
	}

	//最后只能依赖于window.load.
	jQuery.event.add(window, "load", jQuery.ready);
}
这段代码看起来很多,其实就是采用setTimeout(arguments.callee, 0);反复来运行bindReady。如果其得到dom ready的条件满足的话,就执行jQuery.ready()来执行通过$(fn)注册的fn函数。对于每种浏览器,这个满足的条件是不一样。上面的代码就是针对于几种常用的浏览器分别做了各自的处理。
isReady : false,
	readyList : [],
	// Handle when the DOM is ready
		ready : function() {			
			if (!jQuery.isReady) {		
				jQuery.isReady = true;				
				if (jQuery.readyList) {					
					jQuery.each(jQuery.readyList, function() {
						this.call(document);
					});				
					jQuery.readyList = null;
				}				
				jQuery(document).triggerHandler("ready");
			}
		}
	});
当运行到jQuery.ready()的时候就说明dom已经完全的Loaded,那么现在就应该执行保存在jQuery.readyList中的fn。jQuery.ready()就是完成这个工作。

 

分享到:
评论
2 楼 jljlpch 2008-11-09  
{  
latermoon 写道

“其实就是采用setTimeout(arguments.callee, 0);反复来运行bindReady。” 这句话是错误的,bindReady被readyBound限定了只执行一次,arguments.callee指的是所在函数,也就是那个括住setTimeout的匿名函数: (function() {&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (jQuery.isReady)&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 在ondocumentready之前,一直都会抛出异常 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // http://javascript.nwbox.com/IEContentLoaded/&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; document.documentElement.doScroll("left");&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (error) {&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //一直运行bindReady()(=arguments.callee)&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; setTimeout(arguments.callee, 0);&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jQuery.ready();//documentready就运行jQuery.ready&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; })();&nbsp;&nbsp; 可以在其中通过alert(arguments.callee)显示函数。


你说的非常对,当时没有注意到这个匿名函数。它指向是这个匿名函数。
1 楼 latermoon 2008-11-07  
“其实就是采用setTimeout(arguments.callee, 0);反复来运行bindReady。”
这句话是错误的,bindReady被readyBound限定了只执行一次,arguments.callee指的是所在函数,也就是那个括住setTimeout的匿名函数:
(function() {  
            if (jQuery.isReady)  
                return;  
            try {  
                // 在ondocumentready之前,一直都会抛出异常
                // http://javascript.nwbox.com/IEContentLoaded/  
                document.documentElement.doScroll("left");  
            } catch (error) {  
                //一直运行bindReady()(=arguments.callee)  
                setTimeout(arguments.callee, 0);  
                return;  
            }             
            jQuery.ready();//documentready就运行jQuery.ready  
        })();  
可以在其中通过alert(arguments.callee)显示函数。

相关推荐

    jQuery源码分析之Event事件分析

    对于事件的操作无非是addEvent,fireEvent,removeEvent这三个事 件方法。... Jquery提供了一个 event的包裹,这个相对于其它的lib提供的有点简单,但是足够使用。 代码如下: //对事件进行包裹。 fix : function(e

    requirejs-domready-2.0.1-1.zip

    jamppa.zip,jamppa是一个xmpp客户机/组件库

    前端项目-domready.zip

    前端项目-domready,modern domready

    domReady的实现案例

    下面小编就为大家带来一篇domReady的实现案例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

    前端项目-require-domReady.zip

    前端项目-require-domReady,An AMD loader plugin for detecting DOM ready

    JS仿JQuery选择器功能

    JQuery作为应用最广的JS库,其最强大的功能之一就是几乎涵盖所有方法的且代码十分简短的选择器功能,我们也可用自己的代码实现此功能,代码逻辑、使用方法与JQuery一致 function ZQuery(arg){ this.elements = [];...

    domready:domReady 的 Shim 存储库

    准备好 Shim 存储库。 包管理器 : components-domready : components/domready : components/domready

    domReady:Bower-domReady

    domReady 一个用于检测DOM就绪的AMD加载程序插件。 已知可在RequireJS中使用,但应在支持相同加载器插件API的其他AMD加载器中运行。 文件 请参阅。 最新发布 最新版本可从“最新”标签获得。 执照 麻省理工学院 ...

    domReady:跨浏览器 DOM 就绪事件检测

    准备好 跨浏览器 DOM 就绪事件检测功能,能够在 DOM 加载和交互后对任意数量的回调进行排队。 用法 domReady ( function ( ) { // dom is loaded! } ) ;

    jQuery-LCN-Range-Select

    如果添加属性data-auto-init,则在触发domReady事件时,输入元素将自动增强。 &lt;input type="text" class="range-select" data-auto-init value="0;100"&gt; 3.包括脚本和样式 &lt;link rel="stylesheet" href...

    jquery 新建的元素事件绑定问题解决方案

    如果在domready之后用js动态添加几行,那新增的几行中的这些按钮都将失去任何作用,下面与大家分享四种解决方法

    jQPlaceholder:占位符 polyfill 与 jQuery 一起使用

    占位符填充一个处理不支持占位符的浏览器的 jQuery 插件Polfill 使用跨度###placeholder.js 下载placeholder.js polyfill 的工作原理是在输入元素之后插入一个与输入元素具有相同大小的跨度,然后使用负边距将其定位...

    jquery构造器的实现代码小结

    jQuery的$符号非常神奇,它可以接受一个字符,也可以接受一个文档对象或window对象,亦可以传个函数进行变为domReady加载器

    dooomrdy:同构 DOMReady - 只是节点中的 nextTicks

    末日 同构 DOMReady - 只是节点中的 nextTicks。

    JS DOMReady事件的六种实现方法总结

    下面小编就为大家带来一篇JS DOMReady事件的六种实现方法总结。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

    elo:低保真 JavaScript 事件模块

    elo是一个低保真跨浏览器 JavaScript 事件 API,gzips &lt;3k。 这是一个极简主义者的...) $.domReady(fn) // 当 DOM 准备好时调用fn $.hasEvent(eventName, element|tagName?) $(stack).on(eventName, handler) $(st

    JS框架Cyer.zip

    Cyer是一个轻量、小巧的js框架,精简易懂的API设计,支持链式调用,有点jQuery的味道。核心部分为选择器(selector)、dom操作、event机制。暂不支持animate功能。版本更新到v1.0.3,增加domReady事件,只要dom结构...

    一些主流JS框架中DOMReady事件的实现小结

    在实际应用中,我们经常会遇到这样的场景,当页面加载完成后去做一些事情:绑定事件、DOM操作某些结点等。

Global site tag (gtag.js) - Google Analytics