发布在:事件

jQuery 事件的历史

在 jQuery 的演变过程中,事件绑定的方式因各种原因而改变,从性能到语义。从 jQuery v1.7 开始,.on() 方法是直接绑定事件和创建委托事件的公认方式。本文旨在探讨从 jQuery v1.0 到现在的事件委托的历史,以及每个版本如何利用它。

给定以下 HTML,对于我们的示例,我们希望在每次单击时将每个 <li> 的文本记录到控制台。

1
2
3
4
5
6
7
8
9
<div id="container">
<ul id="list">
<li>Item #1</li>
<li>Item #2</li>
<li>Item #3</li>
<li>...</li>
<li>Item #100</li>
</ul>
</div>

链接 .bind()(已弃用)

在 jQuery v1.0 中引入

可以使用 .bind() 并将处理程序附加到每个元素。

1
2
3
4
​$( "#list li" ).bind( "click", function( event ) {
var elem = $( event.target );
console.log( elem.text() );
});​​​​​​​​​​​​​​​​​​​​​

事件委托 文章中所述,这不是最佳选择。

链接 liveQuery

liveQuery 是一个流行的 jQuery 插件,它允许创建事件,这些事件将针对现在或将来存在的元素触发。此插件不使用事件委托,而是使用昂贵的 CPU 处理每 20 毫秒轮询一次 DOM 的更改,并相应地触发事件。

链接 .bind() 委托(已弃用)

在 jQuery v1.0 中引入

通常我们不会将 .bind()事件委托关联起来,但在 jQuery v1.3 之前,它是我们唯一可用的委托方式。

1
2
3
4
5
6
​$( "#list" ).bind( "click", function( event ) {
var elem = $( event.target );
if ( elem.is( "li" ) ) {
console.log( elem.text() );
}
});​​​​​​​​​​​​​​​​​​​​​

我们可以通过将单击事件附加到父 <ul> 元素来利用此处的事件冒泡。每当单击 <li> 时,事件都会冒泡到其父级 <ul>,从而执行我们的事件处理程序。我们的事件处理程序检查 event.target(导致事件触发的元素)是否与我们的选择器匹配。

链接 .live()(已弃用)

在 jQuery v1.3 中引入

所有 .live() 事件处理程序默认绑定到文档根。

1
2
3
4
​$( "#list li" ).live( "click", function( event ) {
var elem = $( this );
console.log( elem.text() );
});​​​​​​​​​​​​​​​​​​​​​

当我们使用 .live() 时,我们的事件绑定到 $( document )。当单击 <li> 时,会发生冒泡,并且我们的单击事件会针对以下每个元素触发

  • <ul>
  • <div>
  • <body>
  • <html>
  • 文档

接收单击事件的最后一个元素是文档,这是我们的 .live() 事件绑定到的位置。.live() 然后将检查我们的选择器 #list li 是否是触发事件的元素,如果是,则执行我们的事件处理程序。

链接 .live() w/ 上下文(已弃用)

在 jQuery v1.4 中引入

自 v1.0 以来,一直支持将上下文作为第二个可选参数传递给 $() 函数。但是,直到 v1.4 才添加了使用此上下文$.live() 方法的支持。

如果我们采用我们之前的 .live() 示例并为其提供默认上下文,它将如下所示

1
2
3
4
​$( "#list li", document ).live( "click", function( event ) {
var elem = $( this );
console.log( elem.text() );
});​​​​​​​​​​​​​​​​​​​​​

由于我们在使用 .live() 方法时可以覆盖上下文,因此我们可以指定一个更接近 DOM 层次结构中元素的上下文

1
2
3
4
$( "li", "#list" ).live( "click", function( event ) {
var elem = $( this );
console.log( elem.text() );
});​​​​​​​​​​​​​​​​​​​​​

在这种情况下,当单击 <li> 时,事件仍然会像以前一样一直冒泡到文档树。但是,我们的事件处理程序现在绑定到父 <ul> 标记,因此我们不必等到事件一直冒泡到文档根。

链接 .delegate()(已弃用)

首先在 jQuery v1.4.2 中引入

.delegate() 方法明确区分了附加委托事件处理程序的上下文和事件冒泡到委托元素时匹配的选择器

1
2
3
4
$( "#list" ).delegate( "li", "click", function( event ) {
var elem = $( this );
console.log( elem.text() );
});​​​​​​​​​​​​​​​​​​​​​

链接 .on()

首先在 jQuery v1.7 中引入

.on() 方法为创建直接绑定事件和委托事件提供了语义化方法。它消除了使用已弃用的 .bind().live().delegate() 方法的需要,提供了一个用于创建事件的单一 API。

1
2
3
4
$( "#list" ).on( "click", "li", function( event ) {
var elem = $( this );
console.log( elem.text() );
});​​​​​​​​​​​​​​​​​​​​​

链接 摘要

所有这些事件委托方法在发布时都是创新的,并被认为是最佳实践。根据你已实现的 jQuery 版本,使用适当的事件委托方法。