如何避免 300ms 的点击延迟
- head标签新增 meta
- css,html新增 touch-action ```jsx // html
// css html { touch-action: manipulation; }
[FAQ - Ant Design Mobile](https://mobile.ant.design/zh/guide/faq#%E5%A6%82%E4%BD%95%E9%81%BF%E5%85%8D-300ms-%E7%9A%84%E7%82%B9%E5%87%BB%E5%BB%B6%E8%BF%9F)
<a name="PDLZ8"></a>
## fastclick
处理移动端点击,延迟 300ms 问题<br />FastClick 是 FT Labs 专门为解决移动端浏览器 300 毫秒点击延迟问题所开发的一个轻量级的库
实现原理:
1. 在检测到 touchend事件的时候,会通过DOM自定义事件立即出发模拟一个click事件
2. 并把浏览器在300ms之后的click事件阻止掉
[https://github.com/ftlabs/fastclick/](https://github.com/ftlabs/fastclick/)
```javascript
<script type='application/javascript' src='/path/to/fastclick.js'></script>
if ('addEventListener' in document) {
document.addEventListener('DOMContentLoaded', function() {
FastClick.attach(document.body);
}, false);
}
es6引入
var FastClick = require('fastclick');
FastClick.attach(document.body, options);
fastclick移动端配置
对index.html进行移动端的配置,fastclick是解决移动端300ms延迟的方案
<script src="/fastclick/1.0.6/fastclick.js"></script>
<script>
if ('addEventListener' in document) {
document.addEventListener('DOMContentLoaded', function() {
FastClick.attach(document.body);
}, false);
}
</script>
react配置 fastclick
import FastClick from 'fastclick';
FastClick.attach(document.body, options);
if (window.FastClick) {
window.FastClick.prototype.focus = targetElement => {
/**
* 兼容处理 iOS7,有一些元素(如date、datetime、month等)在setSelectionRange会出现TypeError
* 因为这些元素并没有 selectionStart和selectionEnd的整型数字属性
* 所以一旦引用就会报错,因此排除这些属性才使用setSelectionRange方法
*/
// 兼容移动端 dingding开发
const elementType = ['date', 'time', 'month', 'email'].includes(targetElement.type);
if (window.dd?.ios && targetElement.setSelectionRange && !elementType) {
const { length } = targetElement.value || {};
targetElement.setSelectionRange(length, length);
// 修复bug ios 11.3不弹出键盘,这里加上聚焦代码,让其强制聚焦弹出键盘
targetElement.focus();
} else {
targetElement.focus();
}
};
}
vue fastclick
main.js中引用
import fastclick from 'fastclick'
fastclick.attach(document.body)
不需要使用fastclick的场景
- FastClick是不会对PC浏览器添加监听事件
- Android版 Chrome 32+浏览器,如果设置viewport meta的值为width=device-width,这种情况下浏览器会马上出发点击事件,不会延迟300毫秒
- 所有版本的Android Chrome浏览器,如果设置viewport meta的值有user-scalable=no,浏览器也是会马上出发点击事件
- IE11+浏览器设置了css的属性touch-action: manipulation,它会在某些标签(a,button等)禁止双击事件
IE10的为 -ms-touch-action: manipulation
<meta name="viewport" content="width=device-width, initial-scale=1">
如果页面上有一些特定的元素不需要使用 fastclick来立刻触发点击事件,可以在元素的class上添加needsclick
<a class="needsclick">Ignored by FastClick</a>
antd-mobile组件手势操作无效
请检查项目中是不是引入了 fastclick,如果有的话,尝试移除掉再试一下
fastClick原理
https://www.cnblogs.com/ylweb/p/10549040.html
touchstart 事件穿透
说完移动端点击300ms延迟的问题,还不得不提一下移动端点击穿透的问题
可能有人会想,既然click点击有300ms的延迟,那对于触摸屏,我们直接监听touchstart事件不就好了吗?
使用touchstart去代替click事件有两个不好的地方
- touchstart是手指触摸屏幕就触发,有时候用户只是想滑动屏幕,却触发了touchstart事件,这不是我们想要的结果
- 使用touchstart事件在某些场景下可能会出现点击穿透的现象
什么是点击穿透
假如页面上有两个元素A和B。B元素在A元素之上。
- 我们在B元素的touchstart事件上注册了一个回调函数,该回调函数的作用是隐藏B元素;
- 当我们点击B元素,B元素被隐藏了,随后,A元素触发了click事件
- 这是因为在移动端浏览器,事件执行的顺序是touchstart > touchend > click
而click事件有300ms的延迟,当touchstart事件把B元素隐藏之后,隔了300ms,浏览器触发了click事件
- 但是此时B元素不见了,所以该事件被派发到了A元素身上。
- 如果A元素是一个链接,那此时页面就会意外地跳转