jQuery中click与touchstart/touchend事件冲突问题排查
问题原因及解决方案
核心问题:touchstart/touchend里的e.preventDefault()阻止了click事件
移动端浏览器的事件触发逻辑是:touchstart → touchend → 浏览器判断是否为点击行为 → 触发click。你在#main的touch事件里直接调用了e.preventDefault(),这会打断浏览器后续的默认触摸处理流程,包括本该触发的click事件,所以链接的click监听永远不会执行。
overflow属性不是直接原因
#main的overflow: hidden auto只是让元素支持滚动,本身不会导致click失效。它和当前问题没有直接关联,不用怀疑这个属性。
解决办法
根据你的需求,有几种可选方案:
1. 移除touch事件里的e.preventDefault()(最简单)
如果你的touch事件只是用来检测触摸区域,不需要阻止滚动或其他默认行为,直接删掉e.preventDefault()即可:
$("#main").on("touchstart touchend", function(e) { // 去掉e.preventDefault() console.log("touch zone>"); }) $(document).on("click", "#main a", function(e) { e.preventDefault(); console.log("Button click"); });
2. 仅在需要时阻止默认行为(区分滑动和点击)
如果需要保留触摸事件的同时不影响点击,可以记录触摸起始位置,在touchend时判断是否是滑动操作,再决定是否阻止默认行为:
let startX, startY; $("#main").on("touchstart", function(e) { startX = e.touches[0].clientX; startY = e.touches[0].clientY; console.log("touch zone>"); }) $("#main").on("touchend", function(e) { const endX = e.changedTouches[0].clientX; const endY = e.changedTouches[0].clientY; const deltaX = Math.abs(endX - startX); const deltaY = Math.abs(endY - startY); // 滑动位移超过10px时,阻止默认行为(避免页面滚动干扰) if (deltaX > 10 || deltaY > 10) { e.preventDefault(); } console.log("touch zone>"); }) $(document).on("click", "#main a", function(e) { e.preventDefault(); console.log("Button click"); });
3. 直接用touch事件处理链接点击
如果不需要依赖click事件,也可以在touchend时直接监听链接的触摸结束事件:
$("#main").on("touchstart touchend", function(e) { console.log("touch zone>"); }) $("#main").on("touchend", "a", function(e) { e.preventDefault(); console.log("Button click"); });
内容的提问来源于stack exchange,提问作者Renato Ramos
相关产品推荐
相关产品推荐

