移动端常用事件 属性 点击穿透问题的解决方案
移动端事件
在前端的移动web开发中,有一部分事件只在移动端产生,如触摸touch相关的事件,以下是关于移动端事件的小结
1.PC端事件在移动端的兼容问题
1.1 click事件的200~300ms延迟问题
主要原因是,需要双击来放大H5页面,会等待200~300ms来看看是否会点击第二次,来判断是否放大
由于双击缩放功能的存在,click事件触发会有200~300ms的延迟
1.2 dbclick事件失效
双击缩放功能的存在,PC端的dbclick事件也就失效了
2.移动端特有的touch事件
2.1 touch事件与click事件同时触发
touchStart---->touchend----->click(200ms~300ms)
通过e.preventDefault来阻止鼠标的点击事件
2.2 touchstart事件
一点击就触发
<body>
<div>
touch mobile
</div>
<script>
document.querySelector("div").addEventListener("touchstart",(e)=>{
console.log(e.type);
});
</script>
</body>
2.3 touchmove事件
在实际开发中事件执行的频率非常高,会多次重复触发,移动端的计算资源非常宝贵,需要考虑事件的节流
移出事件的目标对象区域的时候,touchmove依然在执行
<body>
<div style="width: 100%;height: 150px;background-color: salmon;">
<p></p>
</div>
<script>
var i = 1;
document.querySelector("div").addEventListener("touchmove", (e) => {
document.querySelector("p").innerHTML = "touchmove: " + e.currentTarget.tagName + ',' + i++;
});
</script>
</body>
2.4 touchend
当手指离开触摸屏时触发
不管在何处离开,touchend的target始终保持不变,即使已经移出了区域
<body>
<div style="width: 100%;height: 150px;background-color: salmon;">
<p></p>
</div>
<script>
var i = 1;
document.querySelector("div").addEventListener("touchmove", (e) => {
document.querySelector("p").innerHTML = "touchmove: " + e.currentTarget.tagName + ',' + i++;
});
//touchend
document.querySelector("div").addEventListener("touchend", (e) => {
console.log(e.type);
});
</script>
</body>
2.5 touchcancel
touchcancel什么时候执行?手指离开屏幕不会触发该事件
模态对话框,被意外的情况打断,比如打手机游戏时突然打进电话,那么该事件就会触发,游戏内的touch失效
2.6 触摸事件
通过打印e输出里面的一些事件信息
2.7 TouchList
如果用户的三指触摸屏幕,与之相关的每根手指都会生成touch对象,共有3个
TouchList里面是touch对象,TouchList是类数组
<body>
<div style="width: 100%;height: 150px;background-color: salmon;">
<p></p>
</div>
<script>
document.querySelector("div").addEventListener("touchend", (e) => {
console.log(Array.isArray(e.changedTouches));
//返回touch对象的个数
document.querySelector("p").innerHTML = e.changedTouches.length;
for(let i = 0; i <e.changedTouches.length; i++){
console.log(e.changedTouches.item(i));
}
});
</script>
</body>
2.8 Touch对象
identifier: 0 //每一个touch对象的唯一标识,通过它追踪每一个touch对象
screenX: 297.6000061035156 ////相对于屏幕
screenY: 302.3999938964844
clientX: 171.76470947265625 //相对于viewport的左边缘,不包含滚动条
clientY: 75
pageX: 171.76470947265625 //相对于document左边缘,会包含滚动条
pageY: 75
radiusX: 16.91176414489746 //半径
radiusY: 16.91176414489746
rotationAngle: 0 //角度
force: 0 //力度
target: div //DOM对象
proto: Touch
3 触摸手势封装相关的框架及事件
手势相关的事件一般就是tap类(触屏)和滑动(swiper)
4 移动端点击穿透问题
4.1 点击穿透问题
点击遮罩层(mask,也要蒙层)上的关闭按钮,蒙层消失后发现触发了按钮下main元素的click事件
原因:主要是touch和click同时存在,touch之后又触发了click
解决方案:
- 只用touch
既然是由于touch之后的click造成的,那么不用click自然解决了这个问题
需要注意a标签的href也是click,需要换成JavaScript:void(0) - 只用click
下下策,因为300ms延迟,如果交互性要求不高可以这么做,但快一点总归是好的 - 拿个东西来挡住
比较笨的办法,不推荐用 - tap延迟350ms再隐藏mask
改动最小,缺点是隐藏mask变慢了 - pointer-eventer
有缺陷,不建议使用