移动端300ms点击事件的延迟

时间:2022-03-10 20:21:00

移动端click事件300ms延迟

移动端click事件300ms的延迟在目前看来,已经是老生常谈了。

以下内容,我会在参考资源的基础上谈谈我对移动端click事件300ms延迟的一些理解。本人愚昧,如有不足,望浏览指正。

300ms延迟的原因

参考资源有谈到,300ms延迟是因为浏览器要判断用户的操作而规定的。浏览器不知道用户的手指离开屏幕之后是否会再次回到屏幕,还是就此结束触摸事件。为了确定用户接下来的操作,浏览器不得不等待一段时间。而浏览器开发者找到了一个最佳时间间隔,就是300ms。

而浏览器需要判断用户是否是双击屏幕以进行缩放页面的操作。如果两次click事件的时间间隔在300ms内,表示用户需要双击缩放页面;如果两次click事件的时间间隔在300ms外,表明用户只是需要触发click事件。

触摸事件

在移动端上,存在触摸(touch)事件、手势(gesture)事件和指针(pointer)事件。后两种事件由于使用的少和浏览器兼容性问题的原因,暂时不做讨论。

触摸事件包括touchstart, touchmove, touchend三个事件。

  • touchstart: 当手指触摸屏幕时触发,即使只有一只手指放在屏幕上也会触发
  • touchmove: 当手指在屏幕上连续滑动时触发,在这个事件期间,可以调用事件对象的preventDefault方法阻止页面滚动。
  • touchend: 当手指从屏幕上移开时触发。

以上三个事件都可以冒泡,同时可以被取消。事件对象包含touches数组,changedTouches数组,targetTouches数组,这三个数组包含着clientX/Y、pageX/Y、screenX/Y、target等属性。一般情况下在touchstart事件对象中读取touches数组获取相应的位置信息,在touchmove和touchend事件下读取changedTouches和targetTouches数组获取相应的位置信息。

click事件

前端工程师对click事件绝对不会陌生,click事件触发的事件处理程序是DOM和用户交互最直接的方式。

click事件是由mousedown事件和mouseup事件组成,同时mousedown和mouseup触发必须在同一个像素点上才会触发click事件。

即鼠标点击: mousedown -> mouseup -> click。如果是在按下鼠标的时候触发mousemove事件,将鼠标移动到其他像素点上,然后再触发mouseup事件,此时click事件是不会被触发的。

触摸事件与click事件

既然click事件在移动端上存在300ms的延迟,那我们直接使用触摸事件来代替click事件不就可以了吗?

这种做法是不行的。平时我们使用手机去浏览信息的时候,会不断的滑动页面。如果使用触摸事件替代click事件,那么会发生一些意想不到的事情。比如说,页面上有一个img标签,外层包含a标签,当点击时跳转到新页面。如果此时将某个事件处理程序绑定到touchstart事件时,在这个img标签上滑动屏幕,就会跳转到其他页面了。这并不是我们想要的结果。

再来看看另一个例子,我在documet对象上绑定了click事件,touchstart事件和touchend事件。通过各自事件的事件对象获取到点击时距离是视觉视口的X、Y距离。

document.addEventListener('click', e => {
let touch = e
console.log('click', touch.clientX, touch.clientY)
}, false)
document.addEventListener('touchstart', (e) => {
let touch = e.touches[0]
console.log('start', touch.clientX, touch.clientY)
}, false)
document.addEventListener('touchend', (e) => {
let touch = e.changedTouches[0]
console.log('end', touch.clientX, touch.clientY)
}, false)

当我在页面上触摸且不滑动时,会相继触发touchstart, touchend, click事件。此时会符合我们的预期。

移动端300ms点击事件的延迟

当我在页面上触摸且滑动时,此时只会触发touchstart, touchend, 而不会触发click事件。原因很简单,因为在在触摸时发生了滑动,此时手指就不在一个像素点上了,所以不会触发click事件。

移动端300ms点击事件的延迟

在移动端最理想的情况是,当用户滑动时不误触发某个事件处理程序,当页面静止时点击某个元素才会触发相应的操作,这是最好的情况。所以click事件在移动端仍然需要,不可丢弃。因此,就存在一些办法去处理移动端300ms延迟的问题。300ms延迟在移动端上的体验太差啦!受不了:)

300ms延迟解决方法

meta视口标签

既然300ms出现的原因是为了判断用户是否需要双击缩放页面的问题,那我们禁止