捕获、冒泡

2020-08-16  本文已影响0人  凉城十月

先捕获后冒泡

捕获冒泡示意图
函数addEventListener(‘click’,function(){}, false),最后可以传一个参数,
默认不传就是false或者传falsy值从内往外执行,冒泡阶段false
truy值从外往内 执行,捕获阶段true

特例:如果一个东西上面既有捕获也有冒泡,跟其他部分无关的时候,捕获和冒泡根据代码顺序执行。

实现点击出现浮层,点击别处关闭浮层的效果

捕获冒泡的例子:
HTML代码:

<div id="wrapper" class="wrapper">
    <button id="clickMe">点我</button>
    <div class="popover" id="popover">
      <input type="checkbox">叽里呱啦
    </div>
</div>

css代码:

.wrapper{
  display: inline-block;
  position: relative;
}
.popover{
  margin-left: 10px;
  border: 1px solid red;
  position: absolute;
  left: 100%;
  top: 0;
  white-space:nowrap;
  padding: 20px;  
  background: white;
  display: none;
}
.popover::before{
  content:'';
  position:absolute;
  top:5px;
  right: 100%;
  border: 10px solid transparent;
  border-right-color: red;
}
.popover::after{
  content:'';
  position:absolute;
  top:5px;
  right: 100%;
  border: 10px solid transparent;
  border-right-color: white;
  margin-right: -1px;
}

JS代码【不用jQuery】:点击按钮打开浮层,点击按钮和浮层以外的地方关闭浮层

clickMe.onclick = function(e){
  popover.style.display = 'block'
//e.stopPropagation()//这句话不写在这里是因为在这里阻止了冒泡,点击浮层还是会关闭浮层,不是我们想要的效果
}
wrapper.onclick = function(e){
  e.stopPropagation() //阻止冒泡
}
document.onclick = function(){
  popover.style.display='none'
}

这里如果不加阻止冒泡的话,点击按钮,事件冒泡出去,会在一瞬间,先执行clickMe的点击事件,再立马执行document的点击事件。肉眼看上去是页面没有任何反应,所以要阻断document层的冒泡。
JS代码【用jQuery】:

$(clickMe).on('click', function(e) {
  $(popover).show()
  //在浮层打开后再启用,节省内存
  $(document).one('click', function(e) {
    $(popover).hide()//并非异步代码,在冒泡结束之前就执行,两种办法:阻止冒泡和setTimeout,在0秒钟后尽快执行
  })
})
$(wrapper).on('click', (e)=>{
  e.stopPropagation()
}

存在一个bug,如果``wrapper`的点击事件改成

$(wrapper).on('click', false); //多选框不能选中

这样写,这个false表示

function(e){
  e.stopPropagation()  //阻止冒泡
  e.preventDefault()  //阻止默认
}

同时阻止了冒泡和默认事件,意思是同时阻止了多选框的选中。
在上述代码中,我们只需要阻止冒泡即可。

上一篇 下一篇

猜你喜欢

热点阅读