资讯专栏INFORMATION COLUMN

JS常用库解密-FastClick

stormjun / 2372人阅读

摘要:但这样副作用也很大,移动端的交互体验全靠触摸,将会干扰其他交互行为的处理,例如滚动拖拽等。方案模拟修复法既然浏览器有这的延迟,那么我们来代替浏览器判断,手动触发事件,这也是的解决方案。

众所周知,移动端在处理点击事件的时候,会有300毫秒的延迟。恰恰是这300毫秒的延迟,会让人有一种卡顿的体验。

这300毫秒的原因,在于早期浏览器的实现中,浏览器不知道用户触摸后,到底想做什么,所以故意等待300毫秒,再触发click事件。

既然我们已经知道了原因了,怎么解决呢?

方案1-粗暴治标法

因为浏览器对click事件的处理,有300ms的延迟,而touchstart几乎是立即执行的,估将所有click事件的监听,改为touchstart事件的监听,即可消除这300ms的延迟。

但这样副作用也很大,移动端的交互体验全靠触摸,touchstart将会干扰其他交互行为的处理,例如滚动、拖拽等。

方案2-模拟修复法

既然浏览器有这300ms的延迟,那么我们来代替浏览器判断,手动触发click事件,这也是fastClick的解决方案。

fastClick的核心代码

FastClick.prototype.onTouchEnd = function(event){

  // 一些状态监测代码 

  // 从这里开始,
  if (!this.needsClick(targetElement)) {
    // 如果这不是一个需要使用原生click的元素,则屏蔽原生事件,避免触发两次click
    event.preventDefault(); 
    // 触发一次模拟的click
    this.sendClick(targetElement, event);
  }
}

这里可以看到,FastClick在touchEnd的时候,在符合条件的情况下,主动触发了click事件,这样避免了浏览器默认的300毫秒等待判断。为了防止原生的click被触发,这里还通过event.preventDefault()屏蔽了原生的click事件。

我们来看看他是怎么模拟click事件的

FastClick.prototype.sendClick = function(targetElement, event) {

  // 这里是一些状态检查逻辑

  // 创建一个鼠标事件
  clickEvent = document.createEvent("MouseEvents");
  // 初始化鼠标事件为click事件
  clickEvent.initMouseEvent(this.determineEventType(targetElement), true, true, window, 1, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null);

  // fastclick的内部变量,用来识别click事件是原生还是模拟
  clickEvent.forwardedTouchEvent = true;

  // 在目标元素上触发该鼠标事件,
  targetElement.dispatchEvent(clickEvent);

我们在网上搜索fastClick,大部分都在说他解决了zepto的点击穿透问题,他是怎么解决的呢?就是上面最后一句,他模拟的click事件是在touchEnd获取的真实元素上触发的,而不是通过坐标计算出来的元素。

最后,原理虽简单,但还是建议大家直接用FastClick而不是自己再实现一个。因为,你看他源码里面的注释,有很多特殊情况的补丁的,自己实现一个精简版难免会漏这漏那。

附录

同步发表于我的博客

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/85888.html

相关文章

  • FastClick 源码解读

    摘要:所有浏览器浏览器不支持安卓中中有属性安卓中中有属性有属性的有属性的所以在不需要的浏览器会直接掉,不会执行下面的所有代码。见源码行,可以看出在响应无操作后,则触发。 其实一直就想花些时间读一读那些优秀的开源库,今天终于下了决定打算死磕下自己,2016年每个月读2-3个优秀的开源库,把源码精彩的地方和自己心得分享给大家。 目录 (一)背景(二)源码解析(三)Zepto 点击穿透与 Fast...

    Chaz 评论0 收藏0
  • 移动端-点透问题 巧妙解决

    摘要:移动端经常出现点透,至于怎么出现的请大家去看一下实现的源码。点透是什么你可能碰到过在列表页面上创建一个弹出层,弹出层有个关闭的按钮,你点了这个按钮关闭弹出层后后,这个按钮正下方的内容也会执行点击事件或打开链接。这个被定义为这是一个点透现象。 移动端经常出现点透,至于怎么出现的请大家去看一下zepto实现tap的源码。 1、点透是什么 你可能碰到过在列表页面上创建一个弹出层,弹出层有个关...

    MockingBird 评论0 收藏0
  • 移动端-点透的解决方法

    摘要:移动端经常出现点透,至于怎么出现的请大家去看一下实现的源码。点透是什么你可能碰到过在列表页面上创建一个弹出层,弹出层有个关闭的按钮,你点了这个按钮关闭弹出层后后,这个按钮正下方的内容也会执行点击事件或打开链接。这个被定义为这是一个点透现象。 移动端经常出现点透,至于怎么出现的请大家去看一下zepto实现tap的源码。 1、点透是什么 你可能碰到过在列表页面上创建一个弹出层,弹出层有个关...

    cpupro 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<