Javascript 简明教程

JavaScript - Event Delegation

JavaScript 中的事件委托是一种技术,它允许我们为父元素附加一个事件侦听器,然后使用事件对象来确定哪个子元素触发了事件。这种方式下,我们可以使用单个事件侦听器来处理多个事件,避免在 DOM 中添加过多的事件侦听器。

Event delegation in JavaScript is a technique that allows us to attach a single event listener to a parent element, and then use the event object to determine which child element triggered the event. This way, we can handle multiple events with a single event listener, and avoid adding too many event listeners to the DOM.

Steps of Event Delegation

1. Attach a Listener to a Common Ancestor

为父元素附加一个事件侦听器,封装你想监视的元素,这代替了为每个元素附加单个事件侦听器。使用诸如 addEventListener 的方法来实现高效的实现。

Attach a single event listener to a parent element, encapsulating the elements you wish to monitor; this is in lieu of attaching individual event listeners for each element. Use methods such as addEventListener for efficient implementation.

2. Check the Target Element

在事件处理程序中检查事件的 target 属性,以便精确定位在共同祖先中触发事件的特定元素。常见的检查涉及审查 tagName、classList 或其他目标元素属性。

Inspect the event.target property within the event handler to pinpoint the specific element that triggered it in its common ancestor. Common checks involve scrutinizing tagName, classList, or other target element properties.

3. Perform the Desired Action

针对已识别的目标元素和任何指定条件,执行所需的动作或功能。这可能涉及修改内容、处理按钮单击,或执行与事件关联的任何自定义逻辑。

Based on the identified target element and any specified criteria, execute the desired action or functionality. This could involve modifying content, handling a button click, or performing any custom logic associated with the event.

Event Delegation Examples

Example: List Item Clicks

在这个示例中,我们使用事件委托来巧妙地管理动态更改的教程列表中的单击事件。<ul> 元素充当所有列表项目的共享祖先,有一个单独的事件侦听器附加到它。

In this example, we employ event delegation to adeptly manage clicks on a dynamically changing list of tutorials. The <ul> element serving as the shared ancestor for all list items has one solitary event listener attached to it.

单击教程后,<li> 会通过我们精心设计的事件处理程序标识自身为此目标,因此,可以在控制台中记录此特定教程的内容。这展示了事件委托在管理动态列表时的简化和可扩展方法。

Upon clicking a tutorial, an <li> identifies itself as the target via our skilfully crafted event handler; consequently, enabling logging of that particular tutorial’s content in the console. This demonstrates the streamlined and scalable approach of event delegation in managing dynamic lists.

<!DOCTYPE html>
<html>
<head>
   <style>
      ul {list-style-type: none; padding: 0;}
      li {margin: 5px;
         padding: 10px;
         border: 1px solid #ccc;
         cursor: pointer;
         max-width: 30%;
      }
   </style>
</head>
<body>
   <ul id="myList">
      <li>Tutorial 1</li>
      <li>Tutorial 2</li>
      <li>Tutorial 3</li>
      <li>Tutorial 4</li>
      <li>Tutorial 5</li>
   </ul>
   <div id = "output"></div>
   <script>
      const output = document.getElementById("output");
	  const myList = document.getElementById("myList")
      myList.addEventListener("click", function(event) {
         if (event.target.tagName === "LI") {
            output.innerHTML += "Tutorial clicked: " +
			event.target.textContent + "<br>";
         }
      });
   </script>
</body>
</html>

Example: Form Control Changes

在此使用事件委托允许监视和记录表单控件值的变化:<form> 元素充当共同祖先,而输入事件侦听器捕获输入字段中的更改。脚本通过在其处理程序中检查目标元素来确认,事件确实与 <input> 相关。因此,消息会记录已修改输入的名称和新值:此动作不仅展示了事件委托的适应性,还展示了其在管理动态表单交互方面的效率。

Employing event delegation here allows for the monitoring and logging of changes in form control values: the <form> element acts as a common ancestor, while an input event listener captures alterations within input fields. The script confirms by examining the target element within its handler, that events are indeed related to an <input>. The message, consequently, logs the modified input’s name and new value: this action not only showcases event delegation’s adaptability but also its efficiency in managing dynamic form interactions.

<!DOCTYPE html>
<html>
<body>
   <form id="myForm">
      <input type="text" name="username" placeholder="Username">
      <input type="password" name="password" placeholder="Password">
      <button type="button">Submit</button>
   </form>
   <div id="message"></div>
   <script>
      const messageElement = document.getElementById("message");
	  const myForm = document.getElementById("myForm")
      myForm.addEventListener("input", function(event) {
         if (event.target.nodeName === "INPUT") {
            messageElement.innerHTML +=
			"Input changed: " + event.target.name +
            " - New value: " + event.target.value+'<br>';
         }
      });
   </script>
</body>
</html>

当一个事件侦听器可以有效地管理多个元素的交互时,事件委托很有价值,它可以减少冗余并提高性能。常见的用例包括处理动态列表、表单交互、表格操作、手风琴或选项卡界面、树结构、下拉菜单、多步骤向导、走马灯和各种交互式 UI 组件。它简化了代码结构,确保了一致性,并很好地适应了动态的内容变化,使其成为网页开发中的通用技术。

Event delegation is valuable in scenarios where a single event listener can efficiently manage interactions for multiple elements, reducing redundancy and improving performance. Common use cases include handling dynamic lists, form interactions, table actions, accordion or tabbed interfaces, tree structures, dropdown menus, multi-step wizards, carousels, and various interactive UI components. It simplifies code structure, ensures consistency, and adapts well to dynamic content changes, making it a versatile technique in web development.