JavaScript addEventListener绑定后立即触发导致弹出层自动隐藏问题
问题原因
你触发InfoPopup的按钮点击事件会沿DOM树向上冒泡到document节点,而你在InfoPopup函数执行时同步给document绑定了click事件监听器,本次冒泡上来的点击事件会立刻触发CloseClick逻辑。此时点击的目标是触发按钮,不属于弹出层内部元素,就会直接执行关闭逻辑,导致弹出层刚显示就被隐藏。
解决方案
推荐以下两种实现简单且兼容性好的方案:
方案1:阻止触发按钮的点击事件冒泡
修改触发InfoPopup的按钮的点击事件代码,添加事件冒泡阻止逻辑:
<!-- 原按钮onclick修改为如下格式,对应替换你的弹出层ID即可 --> <button onclick="InfoPopup('AGTcard'); event.stopPropagation()">打开AGT弹出层</button>
这样按钮的点击事件就不会上传到document节点,不会触发刚绑定的关闭监听器。
方案2:延迟绑定document点击事件
修改InfoPopup函数,将事件绑定逻辑放到下一个事件循环执行,避开本次点击的冒泡周期:
function InfoPopup(in_id){ var popup = document.getElementById(in_id) popup.style.display='block' // 延迟0ms执行,等本次点击冒泡流程结束后再绑定监听器 setTimeout(() => { document.addEventListener('click',CloseClick) console.log('added event listener') }, 0) }
额外优化建议
你原有CloseClick代码存在空引用风险:如果当前没有显示的弹出层,current_poppup为undefined,调用contains方法会抛出JS错误,建议添加判空逻辑:
function CloseClick(e){ var popups = document.getElementsByClassName('popup') var current_poppup; for (var i=0;i<popups.length;i++){ if (popups[i].style.display == 'block'){ current_poppup = popups[i] } } // 先判断current_poppup存在再执行后续逻辑 if (current_poppup && !current_poppup.contains(e.target)){ ClosePopup(current_poppup.id) } }
内容的提问来源于stack exchange,提问作者Nathan Roberts
相关产品推荐
相关产品推荐

