什么是DOM事件委托?

任何人都可以请解释事件代表团在JavaScript中,它是如何有用?

DOM事件委托是通过事件“冒泡”(也就是事件传播)的魔术,通过一个共同的父母而不是每个孩子来响应ui事件的机制。

当元素触发事件时, 会发生以下情况 :

该事件被调度到其目标EventTarget并触发了在那里find的任何事件侦听器。 冒泡事件将触发任何额外的事件侦听器,通过向上追踪EventTarget的父链,检查在每个连续的EventTarget上注册的事件侦听器。 此向上传播将继续直至并包括该Document

事件冒泡为浏览器中的事件委托提供了基础。 现在,您可以将事件处理程序绑定到单个父元素,并且该处理程序将在其任何子节点 (以及它们的任何子节点)上发生时执行。 这是事件代表团。 这是一个在实践中的例子:

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

通过这个例子,如果你点击任何一个<li>节点,你会看到一个"click!" ,即使没有单击处理程序绑定到您单击的<li> 。 如果我们将onclick="..."绑定到每个<li>您将获得相同的效果。

那么有什么好处?

想象一下,你现在需要通过DOM操作dynamic地将新的<li>项添加到上面的列表中:

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

在不使用事件委托的情况下,您必须将"onclick"事件处理程序“重新绑定”到新的<li>元素,以便与其兄弟行为相同。 随着事件代表团,你不需要做任何事情。 只需将新的<li>添加到列表中即可完成。

对于具有绑定到许多元素的事件处理程序的web应用程序来说,这绝对是太棒了,在DOM中dynamic创build和/或删除新元素。 通过事件委托,事件绑定的数量可以通过将它们移动到一个共同的父元素而大大减less,dynamic创build新元素的代码可以与绑定它们的事件处理程序的逻辑分离。

事件委托的另一个好处是事件监听器使用的内存占用总量减less(因为事件绑定的数量减less)。 对于经常卸载的小页面(即,用户经常导航到不同的页面)可能没有太大区别。 但是对于长期的应用程序,这可能是重要的。 当从DOM中删除的元素仍然声明内存(即它们泄露)时,有一些真正难以追踪的情况,而且这种泄漏的内存通常与事件绑定绑定在一起。 通过事件代表,您可以自由地销毁子元素,而无需忘记“解除绑定”事件侦听器(因为侦听器在祖先上)。 这些types的内存泄漏可以被包含(如果没有消除,这有时候很难做到,IE浏览器正在看你)。

下面是一些比较好的具体代码例子:

  • JavaScript事件委托如何工作
  • 事件委托与事件处理
  • jQuery.delegate是事件委托+select器规范
  • 当传递一个select器作为第二个参数时, jQuery.on使用事件委托
  • 没有JavaScript库的事件代表团
  • closuresvs事件代表团 :看看转换代码使用事件代表团的优点
  • 有趣的方法PPK揭露了委托focusblur事件 (这泡)

事件委托允许您避免将事件侦听器添加到特定节点; 相反,事件监听器被添加到一个父代。 该事件监听器分析冒泡的事件以查找子元素上的匹配。

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元素经常被添加并从列表中删除,该怎么办? 添加和删​​除事件监听器将是一场噩梦,特别是如果添加和删除代码在您的应用程序中的不同位置。 更好的解决scheme是将一个事件监听器添加到父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!"); } }); 

首先向父元素添加一个单击事件监听器。 当事件监听器被触发时,检查事件元素以确保它是要作出反应的元素的types。 如果这是一个李元素,繁荣:我们有我们所需要的! 如果它不是我们想要的元素,则该事件可以被忽略。 这个例子很简单–UL和LI是一个简单的比较。 让我们尝试一些更困难的事情。 让我们有一个有很多孩子的父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.... } } } } }); 

http://davidwalsh.name/event-delegate

dom事件代表与计算机科学定义有所不同。

它指的是处理来自父级对象(如表格)的许多元素(如表格单元格)的冒泡事件。 它可以保持代码更简单,特别是添加或删除元素时,并保存一些内存。

授权是一种技术,其中一个对象expression某种行为的外部,但实际上委托负责实施该行为的关联对象。 这听起来非常类似于代理模式,但它有一个很不同的目的。 委托是集中对象(方法)行为的抽象机制。

一般来说:使用代表团作为inheritance的替代。 inheritance是一个很好的策略,当父子对象之间存在密切的关系时,inheritance对象就非常接近。 代表团通常是expression类之间关系的更灵活的方式。

这种模式也被称为“代理链”。 其他几种devise模式使用授权 – 国家,策略和访问者模式依赖于它。

代表团的概念

如果一个父类中有许多元素,并且想要处理它们中的事件,则不要将处理程序绑定到每个元素。 相反,将单个处理程序绑定到它们的父级,并从event.target获取该子级。 本网站提供有关如何实施事件委派的有用信息。 http://javascript.info/tutorial/event-delegation

C#中的委托类似于C或C ++中的函数指针。 使用委托允许程序员封装对委托对象内的方法的引用。 然后可以将委托对象传递给可以调用引用方法的代码,而不必在编译时知道哪个方法将被调用。

看到这个链接 – > http://www.akadia.com/services/dotnet_delegates_and_events.html