使用香草JavaScript在浏览器中进行事件委托

我最喜欢的东西之一jQuery的是(是?)事件委托。特别是.on()方法。

我们选择一个DOM元素,然后我们使用.on()附加在该元素的特定子元素上执行的事件处理程序。

为什么这有用?因为如果您要向DOM动态添加元素,则单个事件侦听器将通过.on()将对所有子项都起作用,即使是在注册事件处理程序之后添加到DOM的子项也是如此。

假设您有一张桌子。在表格内部,我们有一组行,每行都有一个带有单击处理程序的按钮。

您在DOM加载时注册一个事件侦听器:

document.addEventListener('DOMContentLoaded', () => {
  const buttons = document.querySelectorAll('button')

for (const button of buttons) { button.addEventListener(…) } })

但是,如果我们在表中添加新行,那么我们还必须记住注册一个新的事件侦听器。

我们如何使用香草JavaScript复制相同的功能?

我们创建一个on带包装选择器的函数,一个事件类型(a'click'例如字符串),一个子选择器字符串,它将匹配包装选择器的后代。在此函数中,我们首先创建一个循环,然后向与包装器选择器匹配的每个元素添加一个事件侦听器(因此它可以应用于多个包装器选择器)。

然后,如果事件的目标与我们的子选择器(函数的第三个参数)匹配,我们将调用作为第4个参数传递的回调函数,并传递事件:

const on = (selector, eventType, childSelector, eventHandler) => {
  const elements = document.querySelectorAll(selector)
  for (element of elements) {
    element.addEventListener(eventType, eventOnElement => {
      if (eventOnElement.target.matches(childSelector)) {
        eventHandler(eventOnElement)
      }
    })
  }
}

这是我们如何调用此函数的方法:

on('ul', 'click', '.module.complete', event => {
  const item = event.target
  //...your event handler
})

现在,当我们单击与之匹配的元素时.module.complete在下面ul选择器,我们传递的函数中的代码将运行,我们可以从中提取单击的项目引用event.target

免费下载我的JavaScript初学者手册


更多js教程: