当前位置: 首页 > 工具软件 > Live Query > 使用案例 >

动态绑定事件Jquery插件Live Query

裴俊智
2023-12-01
转自: http://www.keakon.cn/bbs/thread-1308-1-1.html

jQuery的事件处理是非常强大的,然而美中不足的是,它只能对当前存在的jQuery对象绑定事件,这就使得动态创建的对象必须再次绑定事件。
虽然jQuery 1.3推出了live函数,可以自动捕捉新增对象的事件,不过支持的事件较少,且有时会因为其他插件未考虑live函数,没有让事件冒泡而使live失 效。

于是出于好奇,我用了下jQuery帮助文档里提到的 Live Query,结果发现实在太方便了。
它的原理和live不同,是每隔20ms搜索通过livequery注册的事件,并重新查找符合的对象进行绑定。
看上去效率虽然比live低,但实际测试还不错。用IE 6不停创建div,CPU占用率大概23%(我的电脑是1.6G双核的);在创建了几百个后,我停止创建,CPU在1秒内就降到4%,再过一会降为0%。 也就是说这个检测肯定做过优化的。
根据文档的说明,我觉得应该是只会检查新增对象及更改过属性的对象,这个效率应该是不成问题的。

下面用代码来说明它的强大。

首先是绑定click事件:
The xhtml code:
  1. <input type="button" value="create" id="create" />  
  2. <script type="text/javascript">  
  3.   $('#create').click(function () {  
  4.     $('<div>点我试试</div>').appendTo('body');  
  5.   });  
  6.   $('div').bind('click', function () {alert('clicked');});  
  7.   //$('div').livequery('click', function () {alert('clicked');});  
  8.   //$('div').livequery(function () {$(this).click(function () {alert('clicked');})});  
  9. </script>  
<input type="button" value="create" id="create" />  <script type="text/javascript">    $('#create').click(function () {      $('<div>点我试试</div>').appendTo('body');    });    $('div').bind('click', function () {alert('clicked');});    //$('div').livequery('click', function () {alert('clicked');});    //$('div').livequery(function () {$(this).click(function () {alert('clicked');})});  </script>

先不要去掉注释,直接看bind方法。点击按钮后创建div,可是点击创建 出来的div完全没反应。原因是bind函数执行时,这些div还没创建,所以不可能绑上事件。
接着换成livequery,方法很简单,直接把bind改成livequery就行了,接口是完全相同的。再试试点击创建的div,发现已经绑上事件 了。
然后看第3种方式,直接给livequery传函数。这种方式最为强大,因为每次livequery发现一个符合条件的新对象,就会执行这个函数,而 this则指向对象本身。所以这种方式除了绑定事件,还能做别的事。
还有种传递2个函数的用法,和前者差不多,只不过第2个函数会在不符合条件时调用,一般是用在hover这种事件。

看完这些代码,似乎觉得livequery也没啥,毕竟live基本上也能做到这些,只不过支持的事件有限。
然而前面我说了,livequery不只是绑定事件,它还能做别的事。

下面就来看个支持jQuery UI的draggable函数的例子:
The xhtml code:
  1. <style type="text/css">  
  2. div {width: 100px; height: 100px; overflow: hidden; background: blue;}  
  3. </style>  
  4. <input type="button" value="create" id="create" />  
  5. <script type="text/javascript">  
  6.   $('#create').click(function () {  
  7.     $('<div>拖我试试</div>').appendTo('body');  
  8.   });  
  9.   $('div').livequery(function () {$(this).draggable();});  
  10. </script>  
<style type="text/css">  div {width: 100px; height: 100px; overflow: hidden; background: blue;}  </style>  <input type="button" value="create" id="create" />  <script type="text/javascript">    $('#create').click(function () {      $('<div>拖我试试</div>').appendTo('body');    });    $('div').livequery(function () {$(this).draggable();});  </script>

试试就知道,新创建的div也能绑定拖动,而无需手动绑定。

或许你看不出这意味着什么,但如果draggable要和droppable配合起来,要求draggable对象只能放入符合条件的droppable 对象里,且draggable和droppable对象的属性是随用户操作而不断变化的。
如果不借助livequery,我不得不手动在每次变化属性时都去重设所有的droppable(可能有几十个),而这种变化在代码中可能有上百处。这是 很难保证每次都正确处理的,而且一旦我需要改动条件与droppable的关系,则这上百处都需要检查一遍,以保证一致性。
但假如借助livequery,我可以单独将条件和droppable的关系列出来,用livequery来连接这种关系。之后就能随意更改对象的条件, 而livequery会自动处理绑定新的关系。

虽然这肯定比不上手动绑定的性能,但将关系抽象出来,极大降低了编程的复杂性,是完全值得推荐的。
还是那句话,只有当性能确实成为问题时,才去关注它。如果只是认为它可能会慢一点就不用了,那这个世界也就不会出现C、C++、Java以及动态语言了, 一定还是汇编语言独霸天下的时代。特别是垃圾回收机制,你不觉得和Live Query很相似吗?
话说回来,jQuery的性能肯定比不上手工打造的JavaScript代码,但编程效率却高了至少5倍,所以还不照样很多人用吗?
如果作者能给出个20ms究竟做了什么的说明,并给个处理大量DOM的性能测试的话,估计使用的人会多很多~

最后补充一句,如果用jQuery 1.3.x,则需要去 Git下载对应的1.1.x版,jQuery官网只有 1.0.x的。
 类似资料: