jQuery 事件绑定方法对比

bind、live、delegate、on 四种事件绑定方法的区别与用法

问题

jQuery 中的 bind()live()delegate()on() 有什么区别?

解答

这四个方法是 jQuery 事件绑定的演进历程,从 bind()on() 逐步优化。

bind()

直接绑定到元素上,不支持动态元素。

// 直接绑定到已存在的元素
$('.btn').bind('click', function() {
  console.log('clicked');
});

// 等价于
$('.btn').click(function() {
  console.log('clicked');
});

问题:动态添加的 .btn 元素不会有事件。

live()

通过事件冒泡到 document 实现委托,支持动态元素。

// 事件委托到 document
$('.btn').live('click', function() {
  console.log('clicked');
});

// 动态添加的 .btn 也能响应点击
$('body').append('<button class="btn">New Button</button>');

问题

  • 所有事件都冒泡到 document,性能差
  • jQuery 1.7 已废弃,1.9 移除

delegate()

指定委托的父元素,比 live() 更高效。

// 事件委托到指定父元素
$('#container').delegate('.btn', 'click', function() {
  console.log('clicked');
});

// 只在 #container 内的 .btn 生效

优点:可以控制事件冒泡的范围。

on()

jQuery 1.7+ 推荐方法,统一了前面所有方法。

// 直接绑定(替代 bind)
$('.btn').on('click', function() {
  console.log('clicked');
});

// 事件委托(替代 delegate)
$('#container').on('click', '.btn', function() {
  console.log('clicked');
  console.log($(this).text()); // this 指向触发事件的 .btn
});

// 绑定多个事件
$('.btn').on('click mouseenter', function(e) {
  console.log(e.type);
});

// 绑定多个事件到不同处理函数
$('.btn').on({
  click: function() {
    console.log('clicked');
  },
  mouseenter: function() {
    console.log('hovered');
  }
});

// 只执行一次
$('.btn').one('click', function() {
  console.log('只触发一次');
});

完整示例

<!DOCTYPE html>
<html>
<head>
  <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
  <div id="container">
    <button class="btn">Button 1</button>
    <button class="btn">Button 2</button>
  </div>
  <button id="add">添加按钮</button>

  <script>
    // 事件委托:动态元素也能响应
    $('#container').on('click', '.btn', function() {
      alert($(this).text());
    });

    // 动态添加按钮
    $('#add').on('click', function() {
      $('#container').append('<button class="btn">New Button</button>');
    });
  </script>
</body>
</html>

方法对比表

方法委托位置动态元素状态
bind()元素自身已废弃
live()document已移除
delegate()指定父元素已废弃
on()可选推荐

关键点

  • on() 是目前唯一推荐的方法,其他都已废弃或移除
  • 事件委托的原理是利用事件冒泡,在父元素上监听子元素事件
  • 委托父元素越接近目标元素,性能越好
  • 动态添加的元素必须使用事件委托才能绑定事件
  • on() 的第二个参数(选择器)决定是直接绑定还是事件委托