`
jljlpch
  • 浏览: 323944 次
  • 性别: 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

    Jquery全集,Jquery总结

    - 避免在DOMReady之外操作DOM,使用 `.on()` 代替 `.bind()` 或 `.click()` 以减少内存占用。 - 使用 `$(document).ready()` 或简写形式 `$(function(){...})` 来确保代码在DOM加载完成后执行。 7. **jQuery 版本...

    35个经典Jquery实例方法

    4. **事件处理(Event Handling)**:`click()`, `mouseover()`, `mouseout()`等方法用于绑定事件处理函数,`on()`是更通用的事件绑定方法,可以处理动态添加的元素。 5. **遍历与过滤(Traversing & Filtering)**...

    Jquery入门ppt

    - 使用`$(document).on("event", selector, handler)`来绑定动态添加的元素的事件。 - 使用`.data()`存储关联数据,减少对DOM的操作。 10. **最佳实践** - 使用最新版本的jQuery,以获得最新的特性和支持。 - ...

    jQuery之$(document).ready()使用介绍

    - Prototype: `Event.observe(document, 'dom:loaded', yourFunction);` - Mootools: `window.addEvent('domready', yourFunction);` - Pure JavaScript: `document.addEventListener('DOMContentLoaded', your...

    一周学会Mootools 1.4中文教程(3)事件

    Mootools中的事件绑定非常直观且高效,其`addEvent`方法与jQuery中的`bind`或`on`类似,用于将事件监听器附加到DOM元素上。例如,以下代码演示了如何使用`addEvent`方法为`&lt;a&gt;`元素绑定点击事件: ```javascript $...

    JS框架Cyer.zip

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

    dojo-release-1.12.2

    5. **dojo/ready** 和 **dojo/domReady**:这两个模块用于确保DOM加载完成后再执行代码,`dojo/ready`是`dojo/domReady`的超集,也等待模块加载。 6. **dojo/store** 和 **dojo/data**:这两个模块是Dojo的数据层,...

    利用dojo进行客户端开发过程

    在实际开发中,我们可以使用 `dom` 模块来操作 DOM 元素,`query` 类似于 jQuery 的选择器,用来查找和操作元素,而 `on` 模块则用于事件监听。例如,我们可以使用 `query` 找到特定元素,然后使用 `on` 注册点击...

Global site tag (gtag.js) - Google Analytics