先捕获后冒泡
捕获冒泡示意图
函数
addEventListener(‘click’,function(){}, false),最后可以传一个参数,默认不传就是false或者传falsy值是 从内往外执行,冒泡阶段falsetruy值是 从外往内 执行,捕获阶段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() //阻止默认
}
同时阻止了冒泡和默认事件,意思是同时阻止了多选框的选中。
在上述代码中,我们只需要阻止冒泡即可。












网友评论