事件流——取消事件冒泡和事件委托

312 阅读1分钟

这是我参与11月更文挑战的第29天,活动详情查看:2021最后一次更文挑战

事件流

事件流是什么?

所谓事件流,就是当触发某个元素的事件时,事件会按照DOM树结构进行传播,传播的过程分为捕获阶段、目标阶段和冒泡阶段三个阶段。

1、捕获阶段:该阶段是由网景公司提出的。按照DOM树结构由document对象向下的顺序传播,直到目标元素为止。

2、目标阶段:该阶段就是指目标元素触发当前事件。

3、冒泡阶段:该阶段是由微软公司提出的,按照DOM树结构由目标元素向上的顺序传播,直到 document对象为止。

取消事件冒泡

当元素注册事件设置为冒泡阶段时,可以通过事件对象的stopPropagation()方法取消事件冒泡。

如下代码展示了事件流和取消事件冒泡的操作:

 <!DOCTYPE html>
 <html lang="en">
 <head>
     <meta charset="UTF-8">
     <title>事件流</title>
     <style>
         #d1{
             width: 200px;
             height: 200px;
             background-color: lightcoral;
             padding: 50px;
         }
         #d2{
             width: 100px;
             height: 100px;
             background-color: yellowgreen;
             padding: 50px;
         }
         #d3{
             width: 100px;
             height: 100px;
             background-color: aquamarine;
         }
     </style>
 </head>
 <body>
 <div id="d1">
     <div id="d2">
         <div id="d3"></div>
     </div>
 </div>
 <script>
     var d1 = document.getElementById('d1');
     d1.addEventListener('click',function () {
         console.log('这是d1... ...')
     },false);
     var d2 = document.getElementById('d2');
     d2.addEventListener('click',function () {
         console.log('这是d2... ...')
     },false);
      var d3 = document.getElementById('d3');
      d3.addEventListener('click',function (event) {
          console.log('这是d3... ...');
          // 取消冒泡阶段
          event.stopPropagation();
     },false);
 </script>
 </body>
 </html>

效果图分析如下所示:

dm1VWF.png


事件委托

当为大量的HTML元素注册相同事件,并且事件的句柄逻辑完全相同时,会造成页面速度下降。不过, 事件流允许在这些HTML元素的共同父级元素注册事件。这种方式被称为事件委托。

如下代码展示了使用事件委托解决代码重复的问题,但需要注意的是:场景不同,用法案例也不同。

 <!DOCTYPE html>
 <html lang="en">
 <head>
     <meta charset="UTF-8">
     <title>事件委托</title>
 </head>
 <body>
 <div id="container">
     <button id="btn1">按钮</button>
     <button id="btn2">按钮</button>
     <button id="btn3">按钮</button>
 </div>
 <script>
    /* var btn1 = document.getElementById('btn1');
     btn1.addEventListener('click',function () {
         console.log('这是一个按钮');
     });
     var btn2 = document.getElementById('btn2');
     btn2.addEventListener('click',function () {
         console.log('这是一个按钮');
     });
     var btn3 = document.getElementById('btn3');
     btn3.addEventListener('click',function () {
         console.log('这是一个按钮');
     });*/
 ​
     // 不降事件绑定给指定元素,而是绑定给共同的父级/祖先元素
    // 事件委托
     var container = document.getElementById('container');
     container.addEventListener('click',function (event) {
         var target = event.target;
         if (target.nodeName === 'BUTTON'){
             console.log('这是一个按钮');
         }
     });
 </script>
 </body>
 </html>