如何避免 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元素是一个链接,那此时页面就会意外地跳转
