移动端触摸事件阻止冒泡后父元素点击还是触发了怎么办?
我在开发移动端列表滑动删除功能时遇到问题。子元素的touchstart事件里用了e.stopPropagation(),但父元素的点击事件还是会被触发,这是为什么呢?
具体场景是这样的:列表项有一个可滑动的删除按钮(子元素),外面包裹着点击跳转的父元素。当手指在子元素滑动时,既要阻止父元素跳转,又不能影响正常点击列表项。但现在的效果是,即使在子元素滑动,松手后父元素的点击事件还是会触发。
尝试过在子元素的touchstart里写:
function handleTouchStart(e) {
e.stopPropagation(); // 已经阻止冒泡了呀
// 处理滑动逻辑...
}
但父元素的click事件监听还是会被触发。难道是移动端事件机制和PC端不同?有没有更好的方式同时阻止冒泡和默认行为?
可以试试这样,在子元素的touchstart事件里,除了调用
e.stopPropagation(),还需要加上e.preventDefault()来阻止默认行为。另外,为了彻底避免父元素的点击事件被触发,可以在touchstart的时候给父元素加一个标志位,用来判断是否需要执行点击逻辑。下面是一个完整的解决方案:
这里的关键点是通过标志位
isTouchMove来区分用户是在滑动还是点击。如果检测到滑动操作,就阻止父元素的点击逻辑;如果没有滑动,则正常执行点击跳转。顺便吐槽一句,移动端事件这块儿真是让人头大,我也踩过类似的坑,希望这个方法能帮你解决问题!
e.stopPropagation()是不够的,因为click事件是独立触发的,它并不完全依赖冒泡机制。你得在touchstart或touchmove里调用e.preventDefault()来阻止默认行为。我之前这样搞的,给子元素加个标志位判断是否滑动过:
记得把
touchstart、touchmove和touchend都绑上,这样就能区分滑动和点击了。别问我为什么知道,被坑过好多次才搞定的。