1.为什么要进行事件委托?
单击HTML按钮后,将消息记录到控制台。
要使其正常工作,您需要选择按钮,然后使用addEventListener()
方法来附加事件监听器:
这就是侦听单个元素(尤其是按钮)上的事件的方式。
监听多个按钮上的事件呢?这是一个可能的实现:
查看Codesandbox演示以了解其工作原理。
迭代按钮列表,for (const button of buttons)
并将新的侦听器附加到每个按钮。另外,在列表中添加或删除按钮时,您必须手动删除或附加事件侦听器。
有没有更好的方法?
幸运的是,使用事件委托模式时,侦听多个元素上的事件仅需要一个事件侦听器。
事件委托使用事件传播机制的细节。若要了解事件委派的工作原理,建议您首先了解事件传播。
2.事件传播
当您单击以下html中的按钮时:
点击事件会触发多少个元素?毫无疑问,按钮本身会收到单击事件。而且...所有按钮的祖先,甚至document
和window
对象。
点击事件分三个阶段传播:
- 捕获阶段 -从开始
window
,document
和根元素,事件潜水向下穿过目标元素的祖先 - 目标阶段 -事件在用户单击的元素上触发
- 冒泡阶段 -最后,事件冒泡通过目标元素的祖先直到根元素
document
和为止window
。
方法的第三个参数captureOrOptions
:
使您可以捕获来自不同阶段的事件。
- 如果
captureOrOptions
缺少参数false
或{ capture: false }
,那么侦听器将捕获目标和气泡阶段的事件 - 如果参数为
true
or{ capture: true }
,则侦听器侦听捕获阶段的事件。
在以下代码示例中,您侦听<body>
元素上发生的捕获阶段的点击事件:
在此Codesandbox演示中,单击按钮时,您可以在控制台中看到事件的传播方式。
好的,事件传播如何帮助捕获多个按钮的事件?
该算法很简单:将事件侦听器附加到按钮的父级,并在单击按钮时捕获冒泡事件。这正是事件委托的工作方式。
3.活动委托
让我们使用事件委托来捕获多个按钮上的点击:
打开Codesandbox演示,然后单击任何按钮-您将看到'Click!'
消息记录到控制台。
事件委托的思想很简单。无需将事件侦听器直接附加到按钮,而是将侦听委托给父对象<div id="buttons">
。单击按钮时,父元素的侦听器将捕获冒泡事件(还记得事件传播吗?)。
使用事件委托需要3个步骤:
步骤1.确定要监视事件的元素的父级
在上面的示例中,<div id="buttons">
是按钮的父元素。
步骤2.将事件侦听器附加到父元素
document.getElementById('buttons') .addEventListener('click', handler)
将事件侦听器附加到按钮的父元素。此事件侦听器也对按钮单击做出反应,因为按钮单击事件在祖先中冒泡(由于事件传播)。
步骤3.使用event.target选择目标元素
单击按钮时,将使用以下参数调用处理程序函数:event
对象。该属性event.target
访问在其上调度了事件的元素,在该示例中为按钮:
作为附带说明,event.currentTarget
指向事件侦听器直接附加到的元素。在示例中,event.currentTarget
是<div id="buttons">
。
现在,您可以看到事件委托模式的好处:与其像以前那样将侦听器附加到每个按钮上,不如通过事件委托,只需一个事件侦听器即可。
4.总结
当发生点击事件(或传播的任何其他事件)时:
- 事件从
window
,document
根元素向下传播,并通过目标元素的祖先(捕获阶段) - 事件发生在目标上(目标阶段)
- 最后,事件通过目标祖先冒泡直到根元素
document
和window
(冒泡阶段)。
这种机制称为事件传播。
事件委托是一种有用的模式,因为您可以仅使用一个事件处理程序来侦听多个元素上的事件。
使事件委派工作需要三个步骤:
- 确定要监视事件的元素的父级
- 将事件侦听器附加到父元素
- 使用
event.target
选择目标元素
原著作者:德米特里·帕夫鲁汀
文章来源:国外
原著链接:
Dmitri Pavlutin Blogdmitripavlutin.comPS:原著文章内容为英文版本,建议使用360极速浏览器进行翻译阅读。