本文介绍在移动端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!")
})
总结
该方法的优点在于,通过增加一次判断,减少了不必要的事件绑定,从而避免了冲突。这种方法避免了编写重复代码,且比第一种方法更符合逻辑,因此推荐使用。
以上就是本文的全部内容,希望能为您的学习或工作提供参考。如有疑问,欢迎留言交流,感谢支持。