事件冒泡与事件捕获

在说明事件冒泡与事件捕获之前,我们先来聊一聊addEventListener() 中的e.target和this的区别。 

this: 返回的是绑定事件的对象(元素),例如,哪个元素绑定了这个点击事件

e.target:返回的是触发事件的元素,例如,点击了哪个元素,就返回那个元素。

事件冒泡

微软提出了名为事件冒泡(event bubbling)的事件流。事件冒泡可以形象地比喻为把一颗石头投入水中,泡泡会一直从水底冒出水面。也就是说,事件会从最内层的元素开始发生,一直向上传播,直到document对象。

<div id="outer">
    <p id="inner">Click me!</p>
</div>

p -> div -> body -> html -> document

事件委托

网景提出另一种事件流名为事件捕获(event capturing)。与事件冒泡相反,事件会从最外层开始发生,直到最具体的元素。

上面的例子在事件捕获的概念下发生click事件的顺序应该是

document -> html -> body -> div -> p

过程图:

 所以1-3是捕获过程,3-4是目标阶段,4-7是冒泡阶段;

所以有一道常见笔试题:问捕获,冒泡与冒泡的顺序是?

答案:捕获---->目标------>冒泡

如何开启冒泡与捕获?

通过addEventListener()的第三个参数

 

<!DOCTYPE html>
<html lang="en">
<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>
    #outer {
      width: 200px;
      height: 200px;
      background-color: salmon;
    }
    #outer p {
      background-color: seagreen;
    }
  </style>
</head>
<body>
  <div id="outer">
    <p id="inner1">
      子盒子1
      <p id="inner2">
        子盒子2
        <p id="inner3">
          子盒子3
        </p>
      </p>
    </p>
  </div>
</body>
<script>
  let inner1 = document.querySelector('#inner1')
  let inner2 = document.querySelector('#inner2')
  let inner3 = document.querySelector('#inner3')
  let outer = document.querySelector('#outer')
  inner3.addEventListener('click',function(e){
    console.log('子盒子3被点击了');
  })
  outer.addEventListener('click',function(e){
    console.log('当前的e.target是'+ e.target.innerHTML);
  },false)  //在冒泡阶段执行 



</script>
</html>

效果:

 

应用:

事件代理(事件委托)

点击每个li就让哪个li改变成对应的颜色。以前就是需要给每个li注册事件,是非常辛苦的,而且访问DOM的次数越多,这就会延长整个页面的交互就绪的事件。

<!DOCTYPE html>
<html lang="en">

<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>
    .color_list {
      display: flex;
      display: -webkit-flex;
    }
    .color_list li {
      width: 100px;
      height: 100px;
      list-style: none;
      text-align: center;
      line-height: 100px;
    }
    .box {
      width: 600px;
      height: 150px;
      background-color: #cccccc;
      line-height: 150px;
      text-align: center;
    }
  </style>
</head>

<body>
  <ul class="color_list">
    <li>red</li>
    <li>orange</li>
    <li>yellow</li>
    <li>green</li>
    <li>blue</li>
    <li>purple</li>
  </ul>
  <script>
    var color_list = document.querySelector(".color_list");
    var colors = color_list.getElementsByTagName("li");
    /* 未使用事件代理 */
    for(let i = 0;i < colors.length;i++){
      colors[i].addEventListener('click',function(e){
        this.style.backgroundColor= e.target.innerHTML
      },false)
    }
   /*  
    使用事件代理 
   color_list.addEventListener('click', function (e) {
      if (e.target.nodeName.toLowerCase() === "li") {
        e.target.style.backgroundColor= e.target.innerHTML
      }
    },false) */
  </script>
</body>

</html>


 

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值