live与livequery

ejohn在最新的一篇博客说到 jquery closest 增加参数数组类型 , 并提到了live这个功能,其他框架库我还没有见过这个功能,记得以前jq官方没有live时,听过过它的一个插件livequery,可以对并不存在的dom结点绑定事件,觉得很有意思,这次就一并简单研究了下:


livequery:

使用:


$('div.noexists').livequery('click',
          function(){
            alert(this.innerHTML);
          }
        );

 

那么即使当前页面没有类为 noexists 的 div 结点,以后当你添加后,


$(document.body).append("<div class='noexist'>test</div>");

 

事件会自动注册到这个结点上面去。

 

原理:

 

看完其源代码后,觉得实现确实不是很难,基本原理就是修改jquery原来的所有DOM更改操作:'append', 'prepend', 'after', 'before', 'wrap', 'attr', 'removeAttr', 'addClass', 'removeClass', 'toggleClass', 'empty', 'remove',在进行官方操作后运行自己的代码:

 

对之前的运行过 livequery 的所有选择符比如这里的div.noexists全部取出来,然后判断是否已经注册过指定事件处理了,如果没有就注册。

 

其中的细节还有对livequery 选择符的注册队列管理,以及清除,暂停一系列机制。


优点:

 

将创建添加元素与事件注册处理,分隔开来,对一类元素设置好livequery后,以后只要专注与内容修改即可,程序会更加有条理。

 

缺点:

 

每次更改任意部分结点内容都要将livequery 选择符重新判断一次,对于性能要求严格以及livequery选择符很多时慎用。



live:

jquery大概在1.3后实现了live,功能与livequery核心大致相同,但实现迥异,jquery利用了delagation,即事件委托机制,早先将事件全部委托给document处理,1.4以后事件委托给元素的context处理,性能更有提高。(As of jQuery 1.4, event bubbling can optionally stop at a DOM element "context")

 

使用:

 

$('div.noexists').live('click',
          function(){
            alert(this.innerHTML);
          }
        );


运行后,click事件注册到 $('div.noexists').context即document上面,当click事件发生时,传播到document处理,从click事件的源目标(target)一直往上找,将第一个符合div.noexists的结点做为事件处理函数的this上下文然后执行事件处理函数。


优化:

 

这次,ejohn之所以要对closest修改,就是因为当多个live选择符时,当触发事件时原先是对每个选择符都执行上述操作:

 

jQuery.each(jQuery.data(this, "events").live || [], function(i, fn){
		if ( check.test(fn.type) ) {
			var elem = jQuery(event.target).closest(fn.data)[0];
			if ( elem )
				elems.push({ elem: elem, fn: fn });
		}
	});

 

这样的话对于下列代码:

 

<html>
  <body>
    <div id="main">
      <div id="test">
        <div id="mouseme"></div>
      </div>
    </div>
  </body>
</html>
$("#mouseme").live("mousemove", ...)
$("#main").live("mousemove", ...)
$("body").live("mousemove", ...) // (plugin A)
$("body").live("mousemove", ...) // (plugin B)


 在jquery1.3.2中:

 

 1.  #mouseme check on #mouseme (load Sizzle)
 2. Return.
 3. #main check on #mouseme (load Sizzle)
 4. Walk up tree.
 5. #main check on #test (load Sizzle)
 6. Walk up tree.
 7. #main check on #main (load Sizzle)
 8. Return.
 9. body check on #mouseme (load Sizzle)
10. Walk up tree.
11. body check on #test (load Sizzle)
12. Walk up tree.
13. body check on #main(load Sizzle)
14. Walk up tree.
15. body check on body (load Sizzle)
16. Return.
17. body check on #mouseme (load Sizzle)
18. Walk up tree.
19. body check on #test (load Sizzle)
20. Walk up tree.
21. body check on #main(load Sizzle)
22. Walk up tree.
23. body check on body (load Sizzle)
24. Return.
25. Sort all element results.
26. Loop through the results to trigger.


jquery1.4 closest增加了参数数组类型

 

	while ( cur && cur.ownerDocument && cur !== context ) {
					for ( selector in matches ) {
						match = matches[selector];

						if ( match.jquery ? match.index(cur) > -1 : jQuery(cur).is(match) ) {
							ret.push({ selector: selector, elem: cur });
							delete matches[selector];
						}
					}
					cur = cur.parentNode;
				}
			}
 


则当前目标对于所有选择符只需walk up tree一次即可!


 1.  #mouseme check on #mouseme (load Sizzle)
 2. #main check on #mouseme (load Sizzle)
 3. body check on #mouseme (load Sizzle)
 4. Walk up tree.
 5. #main check on #test (load Sizzle)
 6. body check on #test (load Sizzle)
 7. Walk up tree.
 8. #main check on #main (load Sizzle)
 9. body check on #main (load Sizzle)
10. Walk up tree.
11. body check on body (load Sizzle)
12. Return.
13. Loop through the results to trigger.


提高了效率

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值