如何仅在鼠标按下与松开都在同一元素时触发点击事件
解决方案
要实现父元素仅响应**按下和松开都在自身区域(非子元素)**的点击事件,同时保留子元素的点击能力,由于click事件本身无法追溯mousedown的触发位置,我们需要通过记录mousedown的目标来实现,这是最合理的非hack方式:
修改后的代码
let isParentMousedown = false; const clicker = document.querySelector('.clicker'); const child = document.querySelector('.child'); // 记录是否在父元素本身触发的鼠标按下 clicker.addEventListener('mousedown', (e) => { isParentMousedown = e.target === clicker; }); // 仅当按下和松开都在父元素本身时触发逻辑 clicker.addEventListener('click', () => { if (isParentMousedown) { alert('background was clicked'); } }); // 子元素保留自身点击逻辑,并阻止冒泡 child.addEventListener('click', (event) => { alert('content was clicked'); event.stopPropagation(); });
.clicker { background: #DADADA; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 20px; text-align: center; gap: 20px; user-select: none; } .child { background: white; width: 100px; height: 100px; display: flex; align-items: center; justify-content: center; }
<div class="clicker"> <div class="child"> Press left mouse button here </div> then release it here </div>
逻辑说明
- 记录按下状态:通过
mousedown事件判断触发源是否为父元素本身,标记状态变量 - 过滤点击事件:父元素的
click事件仅在之前的mousedown是触发自父元素本身时执行逻辑,避免了“子元素按下、父元素松开”的误触发 - 保留子元素能力:子元素的
click事件正常执行,且通过event.stopPropagation()阻止冒泡,避免干扰父元素逻辑
注:无法完全脱离
mousedown/mouseup事件实现,因为click事件的原生机制仅关注最终的松开位置,无法直接获取按下时的目标信息。
内容的提问来源于stack exchange,提问作者Gvz
相关产品推荐
相关产品推荐

