将事件监听器添加到将来的项目(不带jQuery)

时间:2017-09-07 16:16:59

标签: javascript events

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

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

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

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

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

1 个答案:

答案 0 :(得分:4)

jQuery不会为动态创建的元素添加侦听器。它的作用是它具有为您设置事件委派的语法。

你可以通过监听一些容器元素并检查点击的内容来查看处理程序是否应该运行来做同样的事情。

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

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

这是一个有限的实现,因为它只检查event.target以查看它是否与选择器匹配。为了更加彻底,您需要从event.target向上遍历其.parentNode,并检查每一个,直到到达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>