jquery 给动态添加元素 实现点击事件


当我们试图绑定一些事件到DOM元素上的时候,通常会使用以下的四个方法
bind(),on(),live(),delegate()大家应该用的较多的是前两种方法。下面是我对四种方法的理解:

  • Bind(): .bind()是最直接的绑定方法,会绑定指定函数和事件到DOM上,这种方法很好的解决了浏览器在事件处理中的兼容问题,但这个方法还有一些问题。代码:
$( "#members li a" ).bind( "click", function( e ) {} ); 
$( "#members li a" ).click( function( e ) {} ); 

上面的两行代码完成的任务都是一样的,就是把event handler 加到全部匹配的a元素上。这里存在着一些效率方面的问题,一方面,我们隠式地吧点击事件加到了所有的a标签上,这个过程是昂贵的;另一方面在执行的时候也是一种浪费,因为他们都是做了同一件事却执行了很多次(我们可以把它们hook到它们的父元素,通过冒泡可以对它们中的每一个进行区分,然后在执行这个event handle)。
优点

  • 这个方法提供了一种在各种浏览器之间对事件处理的兼容性解决方案
  • 非常方便的绑定事件到元素上
  • .click(), .hover()…这些非常方便的时间绑定,都是bind的一种简化处理方式
  • 对于利用ID选出来的元素是非常好的,不仅仅是很快的可以hook上去(页面只能有一个id),而且当事件发生时,handler可以立即被执行(相当于后面的live,delegate)实现方式

缺点

  • 它会绑定事件到所有被筛选出来的元素上
  • 它不会绑定到在它执行完成后动态添加的那些元素上
  • 当被筛选出来的元素很多时,会出现效率问题
  • 当页面加载完成的时候,才可以进行bind(),所以可能产生效率问题。

.live()
.live()方法用到了事件委托的概念来处理事件的绑定。它和用.bind()来绑定事件是一样的。.live()方法会绑定相应的事件到你所选择的元素的根元素上,即是document元素上。那么所有通过冒泡上来的事件都可以用这个相同的handler来处理了。它的处理机制是这样的,一旦事件冒泡到document上,jQuery将会查找selector/event metadata,然后决定那个handler应该被调用。不过在最新的jquery版本中好像被删掉了。

$( "#members li a" ).live( "click", function( e ) {} );

优点:

  • 这里仅有一次的事件绑定,绑定到document上而不像.bind()那样给所有的元素挨个绑定
  • 那些动态添加的elemtns依然可以触发那些早先绑定的事件,因为事件真正的绑定是在document上
  • 你可以在document ready之前就可以绑定那些需要的事件

缺点:

  • 从1.7开始已经不被推荐了,所以你也要开始逐步淘汰它了。
  • Chaining没有被正确的支持
  • 当使用event.stopPropagation()是没用的,因为都要到达document
  • 因为所有的selector/event都被绑定到document,
    所以当我们使用matchSelector方法来选出那个事件被调用时,会非常慢
  • 当发生事件的元素在你的DOM树中很深的时候,会有performance问题

.Delegate()
.delegate()有点像.live(),不同于.live()的地方在于,它不会把所有的event全部绑定到document,而是由你决定把它放在哪儿。而和.live()相同的地方在于都是用event delegation.推荐使用.delegate() 代替.live()

$( "#members" ).delegate( "li a", "click", function( e ) {} );

优点:

  • 你可以选择你把这个事件放到那个元素上了 chaining被正确的支持了
  • jQuery仍然需要迭代查找所有的selector/eventdata来决定那个子元素来匹配,但是因为你可以决定放在那个根元素上,所以可以有效的减小你所要查找的元素。
  • 可以用在动态添加的元素上

缺点:

  • 需要查找那个那个元素上发生了那个事件了,尽管比document少很多了,不过,你还是得浪费时间来查找。

.On()
其实.bind(), .live(), .delegate()都是通过.on()来实现的,.unbind(), .die(), .undelegate(),也是一样的都是通过.off()来实现的,这是1.8.2的源码:

$( "#members li a" ).on( "click", function( e ) {} ); 
$( "#members li a" ).bind( "click", function( e ) {} ); 

// Live
$( document ).on( "click", "#members li a", function( e ) {} ); 
$( "#members li a" ).live( "click", function( e ) {} );

// Delegate
$( "#members" ).on( "click", "li a", function( e ) {} ); 
$( "#members" ).delegate( "li a", "click", function( e ) {} );

优点:

  • 提供了一种统一绑定事件的方法
  • 仍然提供了.delegate()的优点,当然如果需要你也可以直接用.bind()

缺点:

  • 也许会对你产生一些困扰,因为它隐藏了一前面我们所介绍的三种方法的细节。

结论:

  • 用.bind()的代价是非常大的,它会把相同的一个事件处理程序hook到所有匹配的DOM元素上
  • 不要再用.live()了,它已经不再被推荐了,而且还有许多问题
  • .delegate()会提供很好的方法来提高效率,同时我们可以添加一事件处理方法到动态添加的元素上。
  • 我们可以用.on()来代替上述的3种方法

参考资料:https://www.cnblogs.com/moonr…
http://www.alfajango.com/blog…


发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>