冒泡,捕获,委托,事件的所有秘密一览无余

本篇文章参考以下博文
https://www.jianshu.com/p/d3e9b653fa95

事件冒泡

我们先象征性的举个例子,帮助大家有一个具像的理解,下面有三个盒子,他们嵌套在一起。

<div id="num1" onClick={console.log(1)}>

  <div id="num2" onClick='console.log(2)'>
  
    <div id="num3" onClick='console.log(3)'></div>
    
  </div>
  
</div>

当点击黄色盒子的时候,控制台输出的结果为3,2,1。
在这里插入图片描述虽然点击的是黄色盒子,但是浏览器不管你点的是谁,只关心你点的位置有几个元素,点击黄色区域,有三个元素,所以三个元素都被判定为点击,这个类似于你打了别人肚子一拳,虽然是打在他的衣服上面了,但是人家可不管那个,就判定你打他了。

事件冒泡的输出顺序比较好理解,点击的谁,就从谁开始,一层一层往外扩散,直到扩散到document,还是上面的例子,当你打别人的时候,力量是先传递到衣服上,然后再传递到被打人的肉上,一层一层传递。

事件捕获

事件捕获正好和冒泡相反,修改一下代码

<div id="num1">
    <div id="num2">
      <div id="num3"></div>
    </div>
  </div>
  <script>
  
    let div1 = document.getElementById('num1');
    div1.addEventListener('click', function () {
      console.log(1)
    }, true)
    
    let div2 = document.getElementById('num2');
    div2.addEventListener('click', function () {
      console.log(2)
    }, true)
    
    let div3 = document.getElementById('num3');
    div3.addEventListener('click', function () {
      console.log(3)
    }, true)
    
  </script>

上面添加监听事件的方式是为了修改事件捕获,当addEventListener的第三个参数为true的时候,为事件捕获,默认为false,这次我们还是点击黄色区域,输出结果如下:
在这里插入图片描述
这次顺序完全反了过来,可以理解为,程序在执行过程中,要从上往下执行代码,执行到最外层(粉色)div的时候,发现他有一个点击事件,鼠标点击的位置还正好在他的范围之内,那就先把他执行了,别的以后再说。

这样一层一层往里执行,找到谁就执行谁,所以执行顺序为1,2,3。

事件委托

事件委托的机制源于冒泡,现在有一个<ul>,里面有1000个<li>需要添加监听事件,这个时候就不能一个一个的给<li>添加监听事件了,累死也加不完。

这时候就需要用到刚学习过的事件冒泡了,我们已经知道点击一个<li>的时候,事件会冒泡到<ul>上,那直接给<ul>添加上点击事件就可以了,不管点到哪个<li>上都能触发。

当然了,我们还是要区分到底是点击的哪个<li>的,比如这个例子,<ul>里面有1000个<li>,当我点击其中一个<li>的时候,希望它高亮显示。我们可以用以下方法实现

let ul = document.getElementById('ul');
  ul.addEventListener('click', function (e) {
  
    let id = e.target.getAttribute('id') //获取元素的id属性
    
    let li = document.getElementById(id); //这里id没有加引号,是在使用上面刚刚获取到的id属性
    
    li.classList.add("className1") //添加class属性,可以在className1中写上高亮样式
    
  }, false)

阻止事件冒泡和捕获

有时候我们不想冒泡,点谁就谁执行,别人别捣乱

let ul = document.getElementById('ul');
  ul.addEventListener('click', function (e) {
  
    ...
    
    e.stopPropagation() //加上这个就可以阻止冒泡了,同样也适用于捕获
  })

上面提到了e.target,这个东西能帮我们获取到是谁触发的点击事件,但当使用一些第三方库的组件的时候,e.target可能无法获取到我们想要的元素,这个时候需要使用e.currentTarget,具体详情请查看以下博文

e.target与e.currentTarget多一个current到底经历了什么?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值