关于js的冒泡--新手踩坑案例

先通过一段html代码了解各个div的从属关系

<div id='wrapper' class="wrapper">
  <button id="clickMe">点我</button>
  <div id='popover' class="popover">
    浮层
  </div>
</div>
复制代码

要实现的功能是

  1. 通过button按钮点击后打开浮层

采用对button添加监听事件,默认隐藏浮层,在用户点击后展示浮层。

  1. 点击页面空白区域关闭浮层 实现过程如下所示

1. 监听body

首先考虑对body对象添加监听,内容为点击后隐藏浮层。发现无效后通过对body添加边框看到body高度是根据其内容变化的,所以只占屏幕上方很小一部分。


2. 监听document
  • 同样无效。经分析,在冒泡阶段先触发按钮事件,但因同时存在对document的监听,紧接着触发document监听,所以仍然无法显示图层。

  • 进一步思考后,对wrapper添加e.stopPropagation,即停止传播,由此可阻断冒泡,即可实现上述功能。

clickMe.addEventListener('click', function(e){
  popover.style.display = 'block'
})
wrapper.addEventListener('click', function(e){
  e.stopPropagation()
})
document.addEventListener('click', function(){
  popover.style.display = 'none'
})
复制代码

3. 以上虽然可实现需求,但添加的监听器过多,考虑减少内存的使用,可进行优化:

将对document的监听全部添加到click事件的内部,并使用one方法只监听一次点击事件。

$(clickMe).on('click', function() {
  $(popover).show()
  $(document).one('click', function() {
    $(popover).hide()
  })
})
$(wrapper).on('click', function(e){
  e.stopPropagation()
})
复制代码

需注意,在3中若删除阻断,仍会出现bug,若执意删除,则需更改代码如下:
$(clickMe).on('click', function() {
  $(popover).show()
  setTimeout(function() {
    $(document).one('click', function() {
      $(popover).hide()
    })
  }, 0)
})
复制代码

上述代码中,将document监听放在setTimeout函数中,这里的setTimeout作用在于让其中的内容尽快执行而不是立即执行,若不添加则在button被点击之后会立即调用show和监听,此时会立即对popover绑定hide,在冒泡阶段便会依序执行show和hide,造成bug。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值