One of the hot methodologies in the JavaScript world is event delegation, and for good reason. Event delegation allows you to avoid adding event listeners to specific nodes; instead, the event listener is added to one parent. That event listener analyzes bubbled events to find a match on child elements. The base concept is fairly simple but many people don't understand just how event delegation works. Let me explain the how event delegation works and provide pure JavaScript example of basic event delegation.
事件处理是JavaScript世界中最热门的方法之一,这是有充分理由的。 事件委托使您可以避免将事件侦听器添加到特定节点; 而是将事件侦听器添加到一个父对象。 该事件侦听器分析冒泡的事件以找到子元素的匹配项。 该基地的概念是相当简单的,但很多人并不了解事件委托是如何工作的。 让我解释事件委托的工作原理,并提供基本的事件委托的纯JavaScript示例。
Let's say that we have a parent UL element with several child elements:
假设我们有一个包含多个子元素的父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> </ul>Let's also say that something needs to happen when each child element is clicked. You could add a separate event listener to each individual LI element, but what if LI elements are frequently added and removed from the list? Adding and removing event listeners would be a nightmare, especially if addition and removal code is in different places within your app. The better solution is to add an event listener to the parent UL element. But if you add the event listener to the parent, how will you know which element was clicked?
我们还说,单击每个子元素时需要发生一些事情。 您可以为每个单独的LI元素添加一个单独的事件侦听器,但是如果频繁添加和从列表中删除LI元素怎么办? 添加和删除事件侦听器将是一场噩梦 ,尤其是如果添加和删除代码位于应用程序中的不同位置。 更好的解决方案是将事件侦听器添加到父UL元素。 但是,如果将事件侦听器添加到父级,那么您如何知道单击了哪个元素?
Simple: when the event bubbles up to the UL element, you check the event object's target property to gain a reference to the actual clicked node. Here's a very basic JavaScript snippet which illustrates event delegation:
简单:当事件达到UL元素时,您可以检查事件对象的target属性以获得对实际单击的节点的引用。 这是一个非常基本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!"); } });Start by adding a click event listener to the parent element. When the event listener is triggered, check the event element to ensure it's the type of element to react to. If it is an LI element, boom: we have what we need! If it's not an element that we want, the event can be ignored. This example is pretty simple -- UL and LI is a straight-forward comparison. Let's try something more difficult. Let's have a parent DIV with many children but all we care about is an A tag with the classA CSS class:
首先将click事件侦听器添加到父元素。 触发事件侦听器后,检查event元素以确保它是要响应的元素类型。 如果这是一个LI元素,那就繁荣起来:我们有需要的东西! 如果不是我们想要的元素,则可以忽略该事件。 这个示例非常简单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.matches("a.classA")) { console.log("Anchor element clicked!"); } });Using the Element.matches API, we can see if the element matches our desired target.
使用Element.matches API ,我们可以查看该元素是否与所需目标匹配。
Since most developers use a JavaScript library for their DOM element and event handling, I recommend using the library's method of event delegation, as they are capable of advanced delegation and element identification.
由于大多数开发人员都将JavaScript库用于DOM元素和事件处理,因此我建议使用该库的事件委托方法,因为他们能够进行高级委托和元素标识。
Hopefully this helps you visually the concept behind event delegation and convinces you of delegation's power!
希望这可以帮助您直观地了解事件委派背后的概念,并使您相信委派的力量!
翻译自: https://davidwalsh.name/event-delegate