子贤的独立博客 子贤的独立博客
  • 首页
  • 编程
  • 视频
    • 哔哩哔哩
    • 斗鱼TV
    • VLOG
  • 社交媒体
    • 新浪微博
  • 专题
首页 › 编程 › 关于fastclick.js引发的惨案

关于fastclick.js引发的惨案

James
6年前编程阅读 1,842

前言

有一次我在制作移动端h5页面时,遇到一个很奇怪的bug,ios端在input输入框第一次可以正常触发弹起键盘,但之后却需要长按且很困难才能再次触发该行为,于是我便去仔细了解了下这个怪异的问题,便记录下来。

关于fastclick.js引发的惨案-子贤的独立博客

抓出捣蛋的坏蛋

当时一开始我怀疑是自己的代码写了bug,但是我排查了下,我并没有去编写关于输入框聚焦事件之类的工作代码,苦思冥想,终于在搜索引擎里,看到了类似的问题,文中也提到了这种诡异情况,没错!最后的矛头指向了fastclick.js!于是我屁颠颠的跑去了github上查看issues,原来这个问题已经早有开发者提出:

关于fastclick.js引发的惨案-子贤的独立博客

确定bug发生条件

通过查看该issue,基本可以确定该bug发生的条件了:

  • 移动端为IOS且版本在11.3+的webview中。
  • 引入使用了fastclick.js解决300ms延迟。
  • 页面使用了输入框控件。
关于fastclick.js引发的惨案-子贤的独立博客

解决的方法

仔细查看issue的回复,发现已经有人提出一种解决方法:

根据图片,在fastclick.js源码中进行修改,增加元素focus方法强制弹起,的确解决了这个bug,但是目前不知道这样修改会不会导致其他问题。

深入fastclick.js

经过查阅文档文章可以明确的了解到fastclick.js主要是解决移动端开发的两个问题:

  • click事件300ms延迟
  • 点击穿透问题

300ms延迟

在移动设备上触发click事件,浏览器会等待300ms,以此来判断用户是否想执行双击操作,为了解决这个问题,有两种已知的解决方案:

  1. 将touch系列事件绑定在document上,通过计算touch事件触发的时间及位置来判断是否移动端触发事件,如大家熟悉的zepto.js的tap事件。
  2. 当检测到touchend事件后,通过dom自定义事件立即模拟一个click事件,并用preventDefault阻止300ms后的click事件触发,也就是fastclick.js使用的方案。

fastclick.js的具体工作流程如下:

关于fastclick.js引发的惨案-子贤的独立博客

点击穿透

打个比方有多个元素重叠在同个位置,上层元素绑定touch事件,下层绑定click事件,当上层触发touch事件将有可能触发下层的click事件,这种现象就叫点击穿透。在简书有一篇文章专门讲了如何解决点击穿透的,fastclick.js捕获顶层dom元素(html,body)的click事件,拦截所有请求然后进行判断,是否有touch触发以及阻碍click事件等。

移动页面点击穿透问题解决方案

追溯问题缘由

仔细查看大量文章后,终于缕清了一些思路,在一篇关于framework的issue的解决方案中,有位开发者提到:

关于fastclick.js引发的惨案-子贤的独立博客

我们通过这个回答和stackoverflow链接可以大概了解到发生了什么:

关于fastclick.js引发的惨案-子贤的独立博客

IOS11.3将Safari升级到了11.3,支持新的web API,允许对事件支持(passive:false)被动模式,减少屏幕滚动时的性能损耗和减少防止崩溃现象,且在IOS更新日志中提到:

Updated root document touch event listeners to use passive mode improving scrolling performance and reducing crashes.

针对document的touch事件监听添加(passive:true)被动模式的配置,且根据MDN上的说明,开启此参数后,listener将永远不会调用preventDefault()。

关于fastclick.js引发的惨案-子贤的独立博客

由于fastclick.js采用拦截click事件和监听touch事件去实现的,且对原生focus方法进行了重写,所以可能因此导致了无法重复调起聚焦事件。

另外一个bug

还发现部分开发者反映了另外一个问题,也是因为这个导致的,当静置或锁屏一段时间后,页面将不再响应任何click事件,我们可以通过渐进增强设置被动模式即可解决该bug:

关于fastclick.js引发的惨案-子贤的独立博客

参考资料

  • IOS11.3 fastclick.js相关bug
  • What’s New in Safari -ver 11.1
  • Can’t prevent ‘touchmove’ from scrolling window on IOS
  • can not bring up keyboard instantly in ios 11.3(issue)
  • fastclick解析与ios11.3相关bug原因分析

总结

终于我们又踩过一个坑,跨端兼容一直是件需要耐心的事情,耐心的面对成长路上带来的艰辛,一定会有所收获的!

Javascript
赞赏 赞(1)
Node.js 萌新成长日记(二)
上一篇
记构建IOS工程路途中遇到的史诗级巨坑
下一篇
再想想
暂无评论

Recent Posts

  • React Native 多语言国际化
  • React Native 设置文件路径别名
  • 不要笑大挑战 | 两个憨憨 | 达达倾情出演
  • 黄埔古港 | “哥哥影你啊” | 随剪短片
  • 参观省博物馆 | 展品片段随剪

Recent Comments

  1. SuperMan发表在React Native 多语言国际化
React Native 多语言国际化
5年前
7,388 1 10
React Native 设置文件路径别名
5年前
3,249 0 1
解决charles模拟localhost请求无效问题
6年前
3,590 0 0
Cordova构建IOS应用适配iPhone X
6年前
2,601 0 0
1
  • 1
  • 0
Copyright © 2019-2025 子贤的独立博客. Designed by nicetheme.
粤ICP备19162060号
  • 首页
  • 编程
  • 视频
    • 哔哩哔哩
    • 斗鱼TV
    • VLOG
  • 社交媒体
    • 新浪微博
  • 专题
# Vlog # # Cordova # # ETH # # Css # # Android #
James
32
文章
0
评论
35
喜欢