经常听前辈们说移动端尽量不要使用click,因为在手机上,click会比较迟钝,尽量用touchstart。
但是用touchstart有一个问题:用户在滑动页面的时候要是不小心碰到了相关元素也会触发。所以两者都有缺点。

为什么移动端click会迟钝?

从谷歌开发者文档《300ms tap delay, gone away》中,我看到一句话,翻译后大意是:因为移动端要判断是否是双击,所以单击之后不能立刻触发click,要等上个300ms,知道确认了是不是双击,,,

文档中提到:在2014年后,Chrome 32版本已经把这个延迟去掉了

<meta name="viewport" content="width=device-width">

即,把viewport设置为设备的实际像素,这样就不会有300ms的延迟了。 这种方法受到了 IE/Firefox/Safari(IOS 9.3)的支持。

有时我们还能见到一种方式:

<meta name="viewport" content="initial-scale=1.0">

设置为1.0,即1:1等效缩放,这个在Safari中不支持,其兼容性显然没有第一个强。
(故而,一般移动端项目我们都能看见head中一句话:​​​<meta name="viewport" content="initial-scale=1.0, width=device-width, maximum-scale=1, user-scalable=no">​​ )

当然,我们也可以通过css方式设置:

html{
touch-action: manipulation;
}

(:很有用的一个属性!

touchstart的用法

这里放jQuery写法,js和其用法上相同

$("id/class/标签 名").on('touchstart',function(){
//执行的操作语句
...
})

touchstart与click同时触发

产生原因:
我们可以给一个元素同时绑定两个事件(touchstart和click),但是移动设备能够同时识别它们。

解决方案:

1、原生JS事件对象中的 preventDefault 方法
preventDefault作用:阻止元素默认事件行为的发生。

我们在touchstart回调中这样使用时,一旦浏览器识别touchstart,可以阻止后序click的发生:

const Button=document.getElementById("targetButton");
Button.addEventListener("touchstart",e=>{
e.preventDefault();
console.log("touch事件发生过了");
})
Button.addEventListener("click",e=>{
e.preventDefault();
console.log("click事件发生");
})

2、基于功能函数检测绑定事件
我们当然可以通过判断浏览器是否支持touchstart来判断应该使用哪种点击事件:

const Button=document.getElementById("targetButton");
const clickEvent=(function(){
// document.documentElement指整个页面,用“in”判断ontouchstart是不是其中可以(被识别)的事件
if('ontouchstart' in document.documentElement===true)
return 'touchstart';
else
return 'click';
});
Button.addEventListener(clickEvent,e=>{
console.log("点击事件执行!");
})

3、JS判断userAgent
userAgent,包含了所有客户端的信息,比如:内核、PC端还是移动端…我们玩去哪可以判断其中(字符串)是否包含了Windows或者iPhone或者Android,从而判断该用什么

点击事件的执行顺序

在移动端,手指点击一个元素,会经过以下几个步骤:
touchstart --> touchmove --> touchend --> click