解决JS中touchstart与click事件冲突的两种方案

作者:微光时间:2026-10-22 13:08:51浏览:358

本文介绍在移动端Web开发中,如何避免touchstart与click事件同时触发导致的冲突。通过两种方案解决:一是利用preventDefault阻止后续click事件,简单但依赖浏览器实现;二是通过功能检测动态绑定事件,逻辑更严谨且推荐采用。

前言

移动互联网已成为行业发展的主流方向,国内众多互联网巨头正积极布局这一领域,微信和支付宝便是其中的成功案例,各类APP及Web应用也层出不穷。

本文将详细探讨在JavaScript中解决touchstart事件与click事件冲突的具体方法,以下是详细介绍。

业务场景描述

一、业务场景描述

在对现有PC网站进行移动端适配时,为了提升移动设备上的响应速度并优化用户体验,通常会采用专为移动设备设计的事件机制,例如用touchstart事件替代click事件。

为何这样做能提升效果?根据Google开发者文档的解释:

移动设备浏览器在触发click事件时会延迟300毫秒,以区分“单击”与“双击”。而touchstart事件则在手指触碰屏幕的瞬间立即触发。因此,用touchstart替换click可以为用户每次点击节省300毫秒。在频繁点击或涉及动画流畅度要求较高的场景中,这种技术尤为必要。

然而,回到初始场景,在PC网站适配移动端时,不能简单地替换事件,因为PC端无法识别touchstart事件。

冲突产生的原因

二、冲突产生的原因

虽然可以给元素同时绑定touchstart和click事件,但这正是本文要解决的问题——在移动设备上,这两个事件会发生冲突。

由于移动设备能同时识别这两种事件,当用户点击目标元素时,绑定的touchstart事件与约300毫秒后触发的click事件会依次执行,导致绑定的回调函数被执行两次,这显然不符合预期。

解决方案

三、解决方案

针对上述情境,提供以下两种解决方案:

使用preventDefault方法

(一)使用preventDefault方法

第一种方案是利用事件对象中的preventDefault方法。该方法用于阻止元素的默认行为。有趣的是,当同时绑定touchstart和click事件时,在touchstart回调中调用此方法,可以阻止后续click事件的触发。

从原理上讲,这似乎不合理,因为click事件并非元素的“默认事件”,但浏览器确实实现了这一行为,因此我们可以利用它来解决冲突。具体代码如下:


const Button = document.getElementById("targetButton")
Button.addEventListener("touchstart", e => {
 e.preventDefault()
 console.log("touchstart event!")
})
 
Button.addEventListener("click", e => {
 e.preventDefault()
 console.log("click event!")
})

在浏览器模拟移动设备模式下点击目标元素,控制台仅输出“touchstart event!”,表明click事件已被成功阻止。

总结

该方法的优点是简单直接、高效,能很好地实现目标。缺点在于,阻止click事件的方式依赖于浏览器的具体实现,而非preventDefault的标准原理,这可能带来不确定性。尽管目前尚未发现该方法失效的场景,但仍需注意潜在风险。

基于功能检测绑定事件

(二)基于功能检测绑定事件

我们可以通过判断浏览器是否支持touchstart事件来封装点击事件,使客户端根据当前环境决定绑定哪种事件类型。代码如下:


const Button = document.getElementById("targetButton")
const clickEvent = (function() {
 if ('ontouchstart' in document.documentElement === true)
 return 'touchstart';
 else
 return 'click';
})();
 
Button.addEventListener(clickEvent, e => {
 console.log("things happened!")
})

总结

该方法的优点在于,通过增加一次判断,减少了不必要的事件绑定,从而避免了冲突。这种方法避免了编写重复代码,且比第一种方法更符合逻辑,因此推荐使用。

以上就是本文的全部内容,希望能为您的学习或工作提供参考。如有疑问,欢迎留言交流,感谢支持。

作者最新文章