最新更新时间:2020年09月14日15:37:43
《猛戳-查看我的博客地图-总有你意想不到的惊喜》
本文内容:移动端开发过程中遇到的问题,click事件300ms延迟、点击穿透、1像素边框
click事件300ms延迟
click事件等待约 300ms 的原因,浏览器需要判断用户是否是双击缩放行为,如果是双击就不会触发 click 事件。 因此 click 事件触发代表一轮触摸事件的结束。
- 移动端,对dom元素分别绑定三个事件:onTouchStart、onTouchEnd、onClick
import React from 'react'
let time = 0
export default class Home extends React.Component {
touchStart(){
time = Date.now()
console.log('touchStart')
}
touchEnd(){
console.log('touchEnd',Date.now()-time)
}
click(){
console.log('click',Date.now()-time)
}
render() {
return (
<div
onTouchStart={()=>{this.touchStart()}}
onTouchEnd={()=>{this.touchEnd()}}
onClick={()=>{this.click()}}
>test</div>
)
}
}
- 控制台日志输出结果
- 解决方案
方案 | - |
---|---|
禁用缩放 | <meta name = "viewport" content="user-scalable=no" > |
更改默认视口宽度 | <meta name="viewport" content="width=device-width"> |
引入第三方库 | fastclick (原理:当检测到touchend事件后,会触发自己模拟的click事件) |
- 伪方案
使用 touchstart 代替 click 事件的弊端
第一:如果用户只是想滑动屏幕,却触发了touchstart事件;
第二:touchstart事件在某些场景下会出现点击穿透的现象;
- 扩展
移动端的单次触摸动作,触发的事件执行顺序依次是:touchstart -> touchend -> click
PC端的鼠标单次动作,事件执行顺序依次是:mousedown -> mouseup -> click
点击穿透
- 场景
页面上有两个元素,B元素在A元素之上,B元素的 touchstart 事件隐藏B元素。当点击B元素,B元素隐藏了,300ms之后,A元素触发了click事件。
import React from 'react'
export default class Home extends React.Component {
render() {
return (
<>
<div>B</div>
<div>A</div>
</>
)
}
}
- 产生的原因
移动端浏览器在 touchend事件 之后会等待约 300ms ,如果没有 tap 行为,则触发 click 事件
- 解决方案
页面上全部使用touch事件或者click事件
阻止浏览器默认行为
event.preventDefault()
禁止页面缩放
<meta name="viewport" content="width=device-width, user-scalable=no">
pointer-events
auto 默认值,鼠标或触屏事件不会穿透当前层
none 元素不再是target,监听的元素变成了下层的元素(如果子元素设置成 auto,点击子元素会继续监听事件)
蒙层延迟消失(延迟时间>300ms)
借住第三方库fastclick消除300ms延迟,全局使用click
参考资料
- 无
感谢阅读,欢迎评论^-^