什么是DOM事件委托?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (15)

有人能用JavaScript解释一下事件委派吗?

提问于
用户回答回答于

事件委托允许避免将事件侦听器添加到特定节点;相反,事件侦听器将添加到父节点中。该事件侦听器分析冒泡事件,以找到子元素的匹配项。

JavaScript示例:

假设我们有一个带有几个子元素的父UL元素:

<ul id="parent-list">
<li id="post-1">Item 1</li>
<li id="post-2">Item 2</li>
<li id="post-3">Item 3</li>
<li id="post-4">Item 4</li>
<li id="post-5">Item 5</li>
<li id="post-6">Item 6</li>

我们还说,当单击每个子元素时,需要发生一些事情。可以向每个Li元素添加一个单独的事件侦听器,但是如果Li元素经常被添加并从列表中删除怎么办?添加和删除事件侦听器将是一个噩梦,特别是如果添加和删除代码在应用程序中的不同位置。更好的解决方案是向父UL元素添加事件侦听器。但是,如果将事件侦听器添加到父程序中,如何知道单击了哪个元素?

简单:当事件冒泡到UL元素时,您将检查事件对象的目标属性,以获得对实际单击节点的引用。下面是一个非常基本的JavaScript片段,它演示了事件委托:

// Get the element, add a click listener...
document.getElementById("parent-list").addEventListener("click", function(e) {
// e.target is the clicked element!
// If it was a list item
if(e.target && e.target.nodeName == "LI") {
    // List item found!  Output the ID!
    console.log("List item ", e.target.id.replace("post-"), " was clicked!");
       }
 });

首先,向父元素添加一个单击事件侦听器。让我们有一个带有许多子级的父DIV,但是我们所关心的只是一个带有classA CSS类的A标记:

  // Get the parent DIV, add click listener...
  document.getElementById("myDiv").addEventListener("click",function(e) {
// e.target was the clicked element
if(e.target && e.target.nodeName == "A") {
    // Get the CSS classes
    var classes = e.target.className.split(" ");
    // Search for the CSS class!
    if(classes) {
        // For every CSS class the element has...
        for(var x = 0; x < classes.length; x++) {
            // If it has the CSS class we want...
            if(classes[x] == "classA") {
                // Bingo!
                console.log("Anchor element clicked!");
                // Now do something here....
            }
        }
    }

  }
});
用户回答回答于

DOM事件委托是通过事件“冒泡”(又称事件传播)的魔力,通过单个公共父(而不是每个子)响应UI事件的机制。

当在元素上触发事件时:

事件被分派到它的目标。EventTarget任何发现的事件侦听器都会被触发。鼓泡事件将触发任何其他事件侦听器,方法是按照EventTarget父链向上,检查在每个连续事件目标上注册的任何事件侦听器。此向上传播将持续到并包括Document

事件冒泡为浏览器中的事件委托提供了基础。现在,可以将事件处理程序绑定到单个父元素,并且每当事件发生时,该处理程序将被执行。在它的任何子节点上

<ul onclick="alert(event.type + '!')">
    <li>One</li>
    <li>Two</li>
    <li>Three</li>
</ul>

使用该示例,如果要单击任何一个子节点<li>节点,您将看到"click!",即使没有绑定到<li>你点击了。如果我们捆绑onclick="..."致每一个<li>你会得到同样的效果。

假设现在需要动态添加新的<li>通过DOM操作到上面列表中的项:

var newLi = document.createElement('li');
newLi.innerHTML = 'Four';
myUL.appendChild(newLi);

使用事件委托,必须“重新绑定”"onclick"事件处理程序到新的<li>元素,以便它与其兄弟姐妹的行为方式相同。带着事件委托不需要做任何事情。只要加上新的<li>你就完蛋了。

这对于绑定到许多元素的事件处理程序的Web应用程序来说是绝对了不起的,在这些元素中,新元素是在DOM中动态创建和/或删除的。使用事件委托,通过将事件绑定移到公共父元素,可以大大减少事件绑定的数量,并且动态创建新元素的代码可以与绑定它们的事件处理程序的逻辑分离。

扫码关注云+社区