【JavaScript】29_DOM编程:事件的委派与捕获

68 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第31天,点击查看活动详情

19、事件的委派

只有一个希望:

只绑定一次事件,既可以让所有的超链接,包括当前的和未来新建的超链接都具有这些事件

委派:

就是将本该绑定给多个元素的事件,统一绑定给document,这样可以降低代码复杂度方便维护

思路:

可以将事件统一绑定给document,这样点击超链接时由于事件的冒泡,

会导致document上的点击事件被触发,这样只绑定一次,所有的超链接都会具有这些事件

点击按钮,添加链接

 <body>
     <button id="btn">点我一下</button>
     <hr>
     <ul id="list">
         <li><a href="javascript:;">链接一</a></li>
         <li><a href="javascript:;">链接二</a></li>
         <li><a href="javascript:;">链接三</a></li>
         <li><a href="javascript:;">链接四</a></li>
     </ul>
 ​
     <script>
         const links = document.querySelectorAll('ul a')
         const list = document.getElementById("list")
         const btn = document.getElementById('btn')
 ​
         document.addEventListener('click',(event) => {
             alert(event.target.textContent)
         })
 ​
         //点击按钮后,在ul中添加一个新的li
         btn.addEventListener("click",() => {
             list.insertAdjacentHTML(
                 'beforeend',
                 "<li><a href='javascript:;'>新超链接</a></li>"
             )
         })
     </script>
 </body>

进阶版:在执行代码前,先来判断一下事件是由谁触发

 <body>
     <button id="btn">点我一下</button>
 ​
     <hr />
 ​
     <ul id="list">
         <li><a href="javascript:;">链接一</a></li>
         <li><a href="javascript:;">链接二</a></li>
         <li><a href="javascript:;">链接三</a></li>
         <li><a href="javascript:;">链接四</a></li>
     </ul>
 ​
     <script>
         const list = document.getElementById("list")
         const btn = document.getElementById("btn")
 ​
         // 获取list中的所有链接
         const links = list.getElementsByTagName("a")
 ​
         document.addEventListener("click", (event) => {
             // 在执行代码前,先来判断一下事件是由谁触发
             // 检查event.target 是否在 links 中存在
 ​
             // console.log(Array.from(links))
 ​
             if([...links].includes(event.target)){
                 alert(event.target.textContent)
             }                
         })
            
         // 点击按钮后,在ul中添加一个新的li
         btn.addEventListener("click", () => {
             list.insertAdjacentHTML(
                 "beforeend",
                 "<li><a href='javascript:;'>新超链接</a></li>"
             )
         })
     </script>
 </body>

20、事件的捕获

事件的传播机制:

  • 在DOM中,事件的传播可以分为三个阶段:

    1. 捕获阶段 (由祖先元素向目标元素进行事件的捕获)(默认情况下,事件不会在捕获阶段触发)
    2. 目标阶段 (触发事件的对象)
    3. 冒泡阶段 (由目标元素向祖先元素进行事件的冒泡)
  • 事件的捕获,指事件从外向内的传导,

    当前元素触发事件以后,会先从当前元素最大的祖先元素开始向当前元素进行事件的捕获

  • 如果希望在捕获阶段触发事件,可以将addEventListener的第三个参数设置为true

    一般情况下我们不希望事件在捕获阶段触发,所有通常都不需要设置第三个参数

 <head>
     <meta charset="UTF-8" />
     <meta http-equiv="X-UA-Compatible" content="IE=edge" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
     <title>Document</title>
     <style>
         #box1 {
             width: 300px;
             height: 300px;
             background-color: greenyellow;
         }
 ​
         #box2 {
             width: 200px;
             height: 200px;
             background-color: orange;
         }
 ​
         #box3 {
             width: 100px;
             height: 100px;
             background-color: tomato;
         }
     </style>
 </head>
 <body>
     <div id="box1">
         <div id="box2">
             <div id="box3"></div>
         </div>
     </div>
 ​
     <script>
         const box1 = document.getElementById("box1")
         const box2 = document.getElementById("box2")
         const box3 = document.getElementById("box3")
 ​
         box1.addEventListener("click", event => {
             alert("1" + event.eventPhase) // eventPhase 表示事件触发的阶段
             //1 捕获阶段 2 目标阶段 3 冒泡阶段
         })
 ​
         box2.addEventListener("click", event => {
 ​
             alert("2" + event.eventPhase)
         })
 ​
         box3.addEventListener("click", event => {
             alert("3" + event.eventPhase)
         })
 ​
     </script>
 </body>