DOM事件委托是一种通过单个共同的父元素而不是每个子元素来响应UI事件的机制,通过事件“冒泡”(也称为事件传播)的魔力来实现。
当在一个元素上触发事件时,会发生以下情况:
事件冒泡为浏览器中的事件委托提供了基础。现在,您可以将事件处理程序绑定到单个父元素,并且每当事件发生在其任何子节点上时,该处理程序将被执行(以及它们的子节点)。这就是事件委托。以下是它的实际示例:
<ul onclick="alert(event.type + '!')"> <li>One</li> <li>Two</li> <li>Three</li> </ul>
在这个例子中,如果您点击任何一个子<li>节点,您将看到一个"click!"的警告,即使没有将<li>上的点击处理程序绑定。如果我们将onclick="..."绑定到每个<li>上,您将得到相同的效果。
<li>
"click!"
onclick="..."
那么好处是什么?
假设您现在需要通过DOM操作动态添加新的<li>项到上述列表中:
var newLi = document.createElement('li'); newLi.innerHTML = 'Four'; myUL.appendChild(newLi);
如果不使用事件委托,您将不得不重新绑定"onclick"事件处理程序到新的<li>元素上,以使其与其兄弟元素表现相同。使用事件委托,您不需要做任何事情。只需将新的<li>添加到列表中,完成。
"onclick"
这对于绑定到许多元素的事件处理程序的Web应用程序非常好,其中新元素在DOM中动态创建和/或删除。通过事件委托,事件绑定的数量可以大大减少,将它们移到一个共同的父元素中,并且动态创建元素的代码可以与绑定它们的事件处理程序的逻辑解耦。
事件委托的另一个好处是事件监听器使用的总内存占用量减少(因为事件绑定的数量减少)。对于经常卸载的小页面(即用户经常导航到不同页面),这可能没有太大的影响。但对于长期存在的应用程序来说,它可能是重要的。有一些非常难以跟踪的情况,当从DOM中删除元素时,它们仍然占用内存(即它们泄漏),而且通常这种泄漏的内存与事件绑定有关。使用事件委托,您可以自由地销毁子元素,而不必担心忘记“解绑”它们的事件监听器(因为监听器在祖先元素上)。这些类型的内存泄漏可以被包含(如果不是完全消除,有时真的很难做到。IE,我在看着你)。
以下是一些更好的事件委托的具体代码示例:
focus
blur
DOM事件委托是一种通过单个共同的父元素而不是每个子元素来响应UI事件的机制,通过事件“冒泡”(也称为事件传播)的魔力来实现。
当在一个元素上触发事件时,会发生以下情况:
事件冒泡为浏览器中的事件委托提供了基础。现在,您可以将事件处理程序绑定到单个父元素,并且每当事件发生在其任何子节点上时,该处理程序将被执行(以及它们的子节点)。这就是事件委托。以下是它的实际示例:
在这个例子中,如果您点击任何一个子
<li>
节点,您将看到一个"click!"
的警告,即使没有将<li>
上的点击处理程序绑定。如果我们将onclick="..."
绑定到每个<li>
上,您将得到相同的效果。那么好处是什么?
假设您现在需要通过DOM操作动态添加新的
<li>
项到上述列表中:如果不使用事件委托,您将不得不重新绑定
"onclick"
事件处理程序到新的<li>
元素上,以使其与其兄弟元素表现相同。使用事件委托,您不需要做任何事情。只需将新的<li>
添加到列表中,完成。这对于绑定到许多元素的事件处理程序的Web应用程序非常好,其中新元素在DOM中动态创建和/或删除。通过事件委托,事件绑定的数量可以大大减少,将它们移到一个共同的父元素中,并且动态创建元素的代码可以与绑定它们的事件处理程序的逻辑解耦。
事件委托的另一个好处是事件监听器使用的总内存占用量减少(因为事件绑定的数量减少)。对于经常卸载的小页面(即用户经常导航到不同页面),这可能没有太大的影响。但对于长期存在的应用程序来说,它可能是重要的。有一些非常难以跟踪的情况,当从DOM中删除元素时,它们仍然占用内存(即它们泄漏),而且通常这种泄漏的内存与事件绑定有关。使用事件委托,您可以自由地销毁子元素,而不必担心忘记“解绑”它们的事件监听器(因为监听器在祖先元素上)。这些类型的内存泄漏可以被包含(如果不是完全消除,有时真的很难做到。IE,我在看着你)。
以下是一些更好的事件委托的具体代码示例:
focus
和blur
事件(不会冒泡)