【问题标题】:Add event listener to future item (without jQuery) [duplicate]将事件侦听器添加到未来项目(不带 jQuery)[重复]
【发布时间】:2018-02-16 11:13:50
【问题描述】:

很好奇我是否愿意用 Vanilla JS 编写一个列表应用程序。问题是事件监听器没有被添加到新的列表项中。

我向列表中的现有项目添加了一个删除按钮:

const deleteButton = document.querySelectorAll('span');
deleteButton.forEach(button => button.addEventListener('click', deleteItem));

我想为新项目添加一个删除按钮。

我知道 jQuery 的 on() 方法会为动态创建的事件添加一个侦听器——在 Vanilla JS 中是否有等价物?

【问题讨论】:

  • on 封装了用于直接附加和委托事件处理的逻辑,具体取决于您是否将选择器作为参数添加到 on

标签: javascript events


【解决方案1】:

jQuery 不会为动态创建的元素添加监听器。它的作用是它有一个语法可以为你设置事件委托。

您可以通过侦听某些容器元素并检查单击的内容以查看处理程序是否应该运行来执行相同的操作。

例如,这会在 body 上进行侦听,但建议使用更本地的容器。

document.body.addEventListener("click", function(event) {
  if (event.target.matches("span")) {
    deleteItem.call(this, event);
  }
});

这是一个有限的实现,因为它只检查event.target 以查看它是否与选择器匹配。为了更彻底,您需要从event.target 向上遍历其.parentNodes,并检查每个元素,直到到达this 元素。

这可以很容易地抽象成一个帮助函数来构建你的处理程序。

document.body.addEventListener("click", delegate("span", deleteItem));

function deleteItem(event) {
  console.log("clicked on '%s'", this.textContent);
}

function delegate(selector, handler) {
  return function(event) {
    var targ = event.target;
    do {
      if (targ.matches(selector)) {
        handler.call(targ, event);
      }
    } while ((targ = targ.parentNode) && targ != event.currentTarget);
  }
}
span { color: red; }
<div>
  <span>I'm a span!</span>
  Not a span
  <p>
    <span>Another span!</span>
  </p>
</div>

【讨论】:

  • 委托函数应该有一个处理程序参数(使其可用于一切),但很好的答案;)
  • @Jonasw:是的,刚刚在制作演示时注意到了这一点。更新。感谢您的提醒! :)
  • 太棒了,感谢您的清晰解释。现在开始工作了?
  • 不客气。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-08-17
  • 2017-08-30
  • 1970-01-01
  • 1970-01-01
  • 2012-07-18
  • 2014-12-15
  • 2021-04-17
相关资源
最近更新 更多