jquery事件绑定函数bind.lived.elegate.on区别

考虑如下html片段

1
2
3
4
5
6
<ul id="members">
<li>
<a href="a.html">点击一下有惊喜</a>
<a href="b.html">还真点啊</a>
</li>
</ul>

使用bind方法

bind()方法直接在DOM元素中注册事件类型和事件处理函数。虽然它对浏览器的兼容性很好,但是却有很大的性能问题。

1
2
3
4
5
6
7
$("#members li a").bind( "click", function(e) {
console.log(e)
})
// 或
$("#members li a").click(function(e) {
console.log(e)
})

bind()方法会匹配所有符合条件的元素附加上事件处理程序,这样做很浪费时间,因为绑定的都是同一个事件处理函数。类似于在原生JS中给每个<li>绑定onclick事件。

总结一下

优点:

  1. 跨浏览器兼容性好
  2. 可以方便快捷的接入事件处理程序
  3. 可以使用简写方法(.click().hover()
  4. 对于简单的id选择器,使用bind()方法不但绑定更快,甚至可以立刻调用

缺点:

  1. 对于每一个匹配的元素都会绑定相同的事件处理函数
  2. 不支持动态生成的元素
  3. 处理大量的选择元素会有性能问题
  4. 绑定在页面加载前期完成,可能会造成页面性能问题

使用live方法

live()方法使用事件代理方法来实现(还记得JS的事件代理么?)。它将事件处理函数绑定在根元素上,这样做可以使用一个事件处理程序来监听所有冒泡到根元素的事件。一旦事件冒泡到根元素上,jQuery会根据选择器 / 事件元数据来判断应该调用哪个处理程序。虽然这么做可能对用户交互的性能有一些影响,但初始注册很快。

总结一下

优点:

  1. 只注册一个事件处理函数
  2. 从bind到live升级很容易
  3. 支持动态添加的元素
  4. 可以在DOM加载完成前注册事件

缺点:

  1. jQuery 1.7 之后弃用
  2. Chaining不支持这种方法(不是很懂.jpg)
  3. 选择器基本没有用可以扔掉,因为它只在根元素上注册事件处理程序
  4. 使用event.stopPropagation()没有用,因为事件已经冒泡到document
  5. 需要很大的元数据存储
  6. 事件总是要冒泡到document,如果DOM层次很深,可能会影响性能

使用delegate方法

delegate()方法和live()方法类似,不同的是可以自定义绑定事件处理程序的节点

优点:

  1. 可以选择事件处理程序绑定的节点
  2. Chaining支持这种用法
  3. jQuery仍然需要遍历选择器 / 事件数据来决定匹配,但是可以减少document元数据存储量
  4. 支持动态元素

缺点:

  1. 不能直接从旧版本迁移
  2. 需要查找那个那个元素上发生了那个事件了,尽管比document少很多了,不过,你还是得浪费时间来查找

使用on方法

优点:

  1. 提供了一种统一绑定事件的方法
  2. 仍然和delegate有同样的优点