发布在:事件

理解事件委托

链接 简介

事件委托允许我们将单个事件侦听器附加到父元素,该侦听器将触发所有匹配选择器的后代,无论这些后代现在是否存在还是将来添加。

链接 示例

在课程的剩余部分,我们将参考以下 HTML 结构

1
2
3
4
5
6
7
8
9
10
11
12
<html>
<body>
<div id="container">
<ul id="list">
<li><a href="http://domain1.com">Item #1</a></li>
<li><a href="/local/path/1">Item #2</a></li>
<li><a href="/local/path/2">Item #3</a></li>
<li><a href="http://domain4.com">Item #4</a></li>
</ul>
</div>
</body>
</html>

当我们 #list 组中的锚点被点击时,我们希望将它的文本记录到控制台中。通常,我们可以使用 .on() 方法直接绑定到每个锚点的点击事件

1
2
3
4
5
// Attach a directly bound event handler
$( "#list a" ).on( "click", function( event ) {
event.preventDefault();
console.log( $( this ).text() );
});

虽然这工作得很好,但有一些缺点。考虑一下当我们在绑定上述侦听器之后添加一个新锚点时会发生什么

1
2
// Add a new element on to our existing list
$( "#list" ).append( "<li><a href='http://newdomain.com'>Item #5</a></li>" );

如果我们点击新添加的项目,什么都不会发生。这是因为我们之前附加的直接绑定的事件处理程序。直接事件仅在调用 .on() 方法时附加到元素。在这种情况下,由于我们的新锚点在调用 .on() 时不存在,因此它没有获得事件处理程序。

链接 事件传播

理解事件如何传播是能够利用事件委托的一个重要因素。每当我们的一个锚点标签被点击时,都会触发该锚点的点击事件,然后在 DOM 树中冒泡,触发其每个父点击事件处理程序

  • <a>
  • <li>
  • <ul #list>
  • <div #container>
  • <body>
  • <html>
  • document

这意味着,无论何时单击我们绑定的锚标记之一,实际上都单击了整个文档正文!这称为事件冒泡事件传播

由于我们了解事件冒泡,因此可以创建委托事件

1
2
3
4
5
// Attach a delegated event handler
$( "#list" ).on( "click", "a", function( event ) {
event.preventDefault();
console.log( $( this ).text() );
});

请注意,我们如何将 a 部分从选择器移动到 .on() 方法的第二个参数位置。这个第二个选择器参数告诉处理程序侦听指定事件,并在听到事件时检查触发该事件的元素是否与第二个参数匹配。在这种情况下,触发事件是我们的锚标记,它与该参数匹配。由于它匹配,因此我们的匿名函数将执行。我们现在已将一个单击事件侦听器附加到我们的 <ul>,它将侦听其后代锚上的单击,而不是仅将未知数量的直接绑定事件附加到现有锚标记。

链接 使用触发元素

如果该链接是外部链接(此处表示为以“http”开头),我们想要在新窗口中打开该链接,该怎么办?

1
2
3
4
5
6
7
// Attach a delegated event handler
$( "#list" ).on( "click", "a", function( event ) {
var elem = $( this );
if ( elem.is( "[href^='http']" ) ) {
elem.attr( "target", "_blank" );
}
});

这只需将 .is() 方法传递给一个选择器,以查看元素的 href 属性是否以“http”开头。我们还删除了 event.preventDefault(); 语句,因为我们希望发生默认操作(即遵循 href)。

实际上,我们可以通过允许 .on() 的选择器参数为我们执行逻辑来简化我们的代码

1
2
3
4
// Attach a delegated event handler with a more refined selector
$( "#list" ).on( "click", "a[href^='http']", function( event ) {
$( this ).attr( "target", "_blank" );
});

链接 摘要

事件委托是指使用事件传播(冒泡)来处理 DOM 中比事件源元素更高层级的事件的过程。它允许我们为现在或将来存在的元素附加一个事件侦听器。