JS事件冒泡捕获事件代理

一、什么是事件捕获和事件冒泡

事件机制是指当特定的操作(如点击按钮、移动鼠标等)在DOM元素上发生时,会触发相应的事件。JavaScript通过监听事件并绑定对应的处理函数来响应用户的操作,对用户的交互做出响应。

1.1、事件冒泡

如果一个元素的事件被触发,那么他的所有父级元素的同名事件也会被依次触发
元素->父元素->body->html->document->window
事件冒泡一直存在,只不过以前我们没有给父级元素加同名事件

1.2、事件捕获

从最顶级的父元素一级一级往下找子元素触发同名事件,直到触发事件的元素为止
事件捕获,只能通过addEventListener并且参数写true才是事件捕获
其他都是冒泡(不是通过addEventListener添加、addEventListener参数为false
事件对象的stopPropagation方法除了可以阻止冒泡还可以阻止捕获

二、事件流

事件流分为三个阶段

1.捕获阶段
2.目标阶段
3.冒泡阶段。

三、addEventListener

JavaScript中,我们可以使用addEventListener方法来绑定捕获和冒泡事件。

element.addEventListener(event, function, useCapture);

其中,event表示要绑定的事件类型,function表示事件触发时要执行的函数,useCapture是一个可选的参数,用于指定事件是使用捕获还是冒泡阶段进行处理。

useCapturefalse或未提供时,事件将在冒泡阶段进行处理;当useCapturetrue时,事件将在捕获阶段进行处理此时事件不在冒泡,只捕获不冒泡。

<div id="blueBox">
   <div id="yellowBox">
     <div id="greenBox"></div>
   </div>
</div>

<script> 
 let blueBox = document.getElementById('blueBox');
 let yellowBox = document.getElementById('yellowBox');
 let greenBox = document.getElementById('greenBox');
 blueBox.addEventListener('click', () => {
     console.log('blueBox')
 })
 yellowBox.addEventListener('click', () => {
     console.log('yellowBox')
 })
 greenBox.addEventListener('click', () => {
     console.log('greenBox');
 })
</script>

当点击绿色方块时,输出greenBox、yellowBox、blueBox,因为绿色包含在黄色里,黄色和绿色被包含蓝色中。addEventListener不写第三个参数时,事件将在冒泡阶段进行处理,从目标元素开始,逐级向外层元素传播,直到达到最外层的元素,也就是绿色、黄色、蓝色。

image.png

同理,点击黄色时,输出yellowBox、blueBox。点击蓝色时,输出blueBox

如果将第三个参数全部设成true,点击绿色(greenBox),将输出blueBox、yellowBox、greenBox,因为事件将在捕获阶段进行处理,事件捕获的顺序是从最外层的元素开始,逐级向内部元素传播,直到达到目标元素,也就是蓝色、黄色、绿色。

image.png

四、阻止事件冒泡

4.1、event.stopPropagation()

调用该方法会阻止事件继续传播,但不会阻止其他事件处理程序被触发。也就是说,如果一个元素上绑定了多个事件处理程序,调用该方法只会阻止事件传播到更高层级的元素,而不会阻止同一元素上的其他事件处理程序被触发。

 blueBox.addEventListener('click', () => {
     console.log('blueBox')
 }, true);
 yellowBox.addEventListener('click', () => {
     console.log('yellowBox')
 })
 greenBox.addEventListener('click', (event) => {
     console.log('greenBox');
     event.stopPropagation();
 }, true);

在上面的示例中,当点击绿色方块时,调用event.stopPropagation()会阻止事件继续传播到外层元素,所以只会输出"greenBox",而不会输出”yellowBox”和”blueBox”。

四、事件委托

事件委托也称为事件代理(Event Delegation),事件委托是一种将事件处理程序绑定到一个父元素上,而不是将事件处理程序绑定到每个子元素上的技术。通过事件委托,可以减少事件处理程序的数量,提高性能和代码的可维护性。

<ul id="ul">
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
  <li>5</li>
</ul>

<script>
  let li = document.getElementsByTagName("li");
  for (let i = 0; i < li.length; i++) {
    li[i].addEventListener("click", () => {
      console.log(li[i].innerHTML);
    });
  }
</script>

如上述代码所示,点击某一数字,就会输出对应内容。节点少的时候还好,如果节点多达上千上万个,就需要声明相当多的事件函数,比较消耗内存。而且如果列表经常发生动态变更,也会导致大量监听事件的移除和绑定。

在这种情况下,事件委托就可以体现它的优势了。事件委托正是利用事件流的冒泡特性,将本来要绑定到多个元素的事件函数,委托到了其祖先元素上。

优点:节约内存 提升性能(不需要注销子节点)

//事件代理  节约内存 提升性能(不需要注销子节点)
let ul = document.getElementById("ul");
ul.addEventListener("click", (event) => {
    console.log(event.target.innerHTML);
})

我们通过将事件处理程序绑定到父元素ul上,当点击列表项时,通过 event 对象拿到必要的信息,会打印出被点击的列表项的内容。如此这般,不管li有多少,更新多频繁,我们只需要维护一个函数就够了。

  • 23
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值