• 技术文章 >web前端 >js教程

    深入浅析JS中的事件委托

    青灯夜游青灯夜游2021-02-01 17:50:41转载873

    大前端成长进阶课程:进入学习

    为什么要进行事件委托?

    首先实现一个小功能:在单击 HTML 的按钮后,把消息输出到控制台。

    为了实现这个小功能,你需要选择按钮,然后再用 addEventListener() 方法来附加事件监听器:

    <button id="buttonId">Click me</button>
    
    <script>
      document.getElementById('buttonId')
        .addEventListener('click', () => console.log('Clicked!'));
    </script>

    以上就是侦听单个元素(尤其是按钮)上事件的方式。

    如果需要监听多个按钮上的事件呢?下面是一种可能的实现:

    <div id="buttons">
      <button class="buttonClass">Click me</button>
      <button class="buttonClass">Click me</button>
      <!-- buttons... -->
      <button class="buttonClass">Click me</button>
    </div>
    
    <script>
      const buttons = document.getElementsByClassName('buttonClass');
      for (const button of buttons) {
        button.addEventListener('click', () => console.log('Clicked!'));
      }
    </script>

    你可以在 Codesandbox 上查看它是怎样工作的

    按钮列表被迭代为 for (const button of buttons) ,并且每个按钮都被附加了一个新的侦听器。另外在列表中的按钮被添加或删除后,你必须还要手动删除或附加事件监听器。

    有没有更好的方法?

    幸运的是,如果我们使用“事件委托”模式的话,侦听多个元素上的事件只需要一个事件侦听器。

    事件委托使用事件传播机制的细节。想要要了解事件委托的工作原理,应该先了解什么是事件传播。

    事件传播

    当你单击下面 html 中的按钮时:

    <html>
      <body>
        <div id="buttons">
          <button class="buttonClass">Click me</button>
        </div>
      </body>
    </html>

    点击事件会触发多少个元素?毫无疑问,按钮本身会收到单击事件。而且所有按钮的祖先,甚至包括 documentwindow 对象也会收到。

    点击事件的传播分三个阶段:

    1.png

    2.png

    addEventListener 方法的第三个参数 captureOrOptions

    element.addEventListener(eventType, handler[, captureOrOptions]);

    使你可以捕获来自不同阶段的事件。

    通过下面的代码,你会侦听到在 <body> 元素上发生的捕获阶段的点击事件:

    document.body.addEventListener('click', () => {
      console.log('Body click event in capture phase');
    }, true);

    在这个 Codesandbox 演示中,单击按钮时,你可以在控制台中查看事件的传播方式。

    那么事件传播是怎样帮助捕获多个按钮事件的呢?

    该算法很简单:把事件侦听器附加到按钮的父级,并在单击按钮时捕获冒泡事件。这就是事件委托的工作方式。

    3.事件委托

    让我们用事件委托来捕获多个按钮上的点击:

    <div id="buttons"> <!-- Step 1 -->
      <button class="buttonClass">Click me</button>
      <button class="buttonClass">Click me</button>
      <!-- buttons... -->
      <button class="buttonClass">Click me</button>
    </div>
    
    <script>
      document.getElementById('buttons')
        .addEventListener('click', event => { // Step 2
          if (event.target.className === 'buttonClass') { // Step 3
            console.log('Click!');
          }
        });
    </script>

    打开Codesandbox 演示,然后单击任意按钮,你会看到 'Click!' 消息被记录到控制台。

    事件委托的思想很简单。你不需要把委托事件监听器直接附加到按钮上,而是可以委托父监听 <div id="buttons">。单击按钮时,父元素的侦听器将会捕获冒泡事件(还记得前面所说事件传播吗?)。

    使用事件委托需要3个步骤:

    步骤1:确定要监视事件的元素的父级元素

    在上面的例子中, <div id="buttons"> 是按钮的父元素。

    步骤2:把事件侦听器附加到父元素

    document.getElementById('buttons') .addEventListener('click', handler) 将事件侦听器附加到按钮的父元素。该事件侦听器也会对按钮单击做出反应,因为按钮单击事件冒泡通过祖先元素(由于事件传播)。

    步骤3:用 event.target 选择目标元素

    单击按钮时,将会用event 对象参数调用处理函数。属性 event.target 访问在其上调度了事件的元素,在例子中是一个按钮:

    // ...
    .addEventListener('click', event => {
        if (event.target.className === 'buttonClass') {      
            console.log('Click!');
        }
    });

    顺便说明一下,event.currentTarget 指向事件侦听器直接附加到的元素。在例子中,event.currentTarget<div id="buttons">

    现在,你可以看到事件委托模式的好处:事件委托仅需要一个事件侦听器,而不必像本文最初那样将侦听器附加到每一个按钮上。

    总结

    当发生点击事件(或传播的任何其他事件)时:

    该机制称为事件传播

    事件委托是一种有用的模式,因为你可以只需要用一个事件处理程序就能侦听多个元素上的事件。

    使用事件委托需要三个步骤:

    更多计算机编程相关知识,请访问:编程视频!!

    以上就是深入浅析JS中的事件委托的详细内容,更多请关注php中文网其它相关文章!

    声明:本文转载于:51cto,如有侵犯,请联系admin@php.cn删除

    前端(VUE)零基础到就业课程:点击学习

    清晰的学习路线+老师随时辅导答疑

    自己动手写 PHP MVC 框架:点击学习

    快速了解MVC架构、了解框架底层运行原理

    专题推荐:JavaScript 事件委托
    上一篇:angularjs数据绑定失效的解决方法 下一篇:自己动手写 PHP MVC 框架(40节精讲/巨细/新人进阶必看)

    相关文章推荐

    • ❤️‍🔥共22门课程,总价3725元,会员免费学• ❤️‍🔥接口自动化测试不想写代码?• vue和javascript的区别是什么• JavaScript数组遍历的6种方法比较• JavaScript中的错误对象(Error object)• 介绍JavaScript作用域和闭包
    1/1

    PHP中文网