持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第29天,点击查看活动详情
如果您曾经使用过原生 Javascript,你可能熟悉使用以下公式向元素添加事件侦听器:
let element = document.querySelector('#button');
element.addEventListener('click', () => {
console.log('some event content here...')
})
当然,上面的代码会触发一个在触发时触发的函数#button
。但有时,您需要为多个元素添加事件侦听器——例如,页面上存在的每个按钮。您可能已经发现,即使页面上有多个元素,上述方法也只会将您的事件添加到一个元素 - 第一个元素。是什么赋予了?
这个问题addEventListener
只适用于向一个 DOM 元素添加事件 - 并且也querySelector
只匹配一个元素。那么如何为页面上的多个元素添加事件监听器呢?让我们看看解决方案。
向多个元素添加事件侦听器
querySelector
我们将使用querySelectorAll
匹配页面上的所有元素,而不是使用。下面的代码返回一个类型的项目NodeList
,由所有匹配的 DOM 元素组成.button
。要将事件添加到每个元素,我们将需要遍历我们的每个匹配的元素querySelector
,并为每个元素添加事件:
let elements = document.querySelectorAll('.button');
Javascript 很奇怪,因为它不会将 DOM 元素作为简单数组返回 - 它会将它们作为NodeList
在现代浏览器中,NodeList
s 的行为很像数组,因此我们可以使用它forEach
来遍历每个数组。要为每个事件添加一个事件.button
,我们需要使用forEach
. 因此向click
所有.button
元素添加事件如下所示:
let elements = document.querySelectorAll('.button');
let clickEvent = () => {
console.log('some event content here...')
}
elements.forEach((item) => {
item.addEventListener('click', clickEvent)
});
但是,在 Internet Explorer 等较旧的浏览器中, sforEach
上不存在NodeList
。尽管这在现代不是问题,但您可能会发现将结果querySelectorAll
更改为数组并循环遍历的代码。这实现了同样的事情,但这意味着我们正在循环遍历数组,而不是NodeList
s。
let elements = document.querySelectorAll('.button');
let clickEvent = () => {
console.log('some event content here...')
}
Array.prototype.forEach.call(elements, (item) => {
item.addEventListener('click', clickEvent);
});
事件委托方法
实现此目的的另一种方法是通过事件委托。这是您将点击事件分配给父级的地方,然后检查用户在父级中单击的位置。这是可以做到的,因为事件冒泡到 Javascript 中的父元素。这也意味着您只需要编写一个函数,而不是循环遍历并将函数添加到多个元素。
为此,我们使用e.target
跟踪实际点击了哪个元素 - 因为e.target
保存了有关触发初始事件的 DOM 元素的信息。
鉴于我们有一些这样的 HTML:
<div id="holder">
<div class="button">Hi</div>
<div class="button">Hi</div>
<div class="button">Hi</div>
</div>
我们可以添加一个事件并检查是否单击#holder
了该类的任何项目。.button
这更有效,意味着我们不必使用for
orforEach
循环:
let element = document.getElementById('holder');
element.addEventListener('click', (e) => {
if(e.target.classList.contains('button')) {
console.log('some event content here...');
}
});