读Zepto源码之Gesture模块

Gesture 模块基于 IOS 上的 Gesture 事件的封装,利用 scale 属性,封装出 pinch 系列事件。

读 Zepto 源码系列文章已经放到了github上,欢迎star: reading-zepto

源码版本

本文阅读的源码为 zepto1.2.0

GitBook

reading-zepto

整体结构

;(function($){
  if ($.os.ios) {
    var gesture = {}, gestureTimeout

    $(document).bind('gesturestart', function(e){
     ...
    }).bind('gesturechange', function(e){
      ...
    }).bind('gestureend', function(e){
     ...
    })

    ;['pinch', 'pinchIn', 'pinchOut'].forEach(function(m){
      $.fn[m] = function(callback){ return this.bind(m, callback) }
    })
  }
})(Zepto)

注意这里有个判断 $.os.ios ,用来判断是否为 ios 。这个判断需要引入设备侦测模块 Detect 。这个模块利用 userAgent 来进行设备侦测,里面是一大堆正则表达式,所以这个模块后面是不打算分析的了。

然后是监测 gesturestartgesturechangegestureend 事件,根据这三个事件,可以组合出 pinchpinchInpinchOut 事件。其实就是缩小和放大的手势操作。

其中变量 gesture 对象和 Touch 模块中的 touch 对象的作用差不多,可以先看看 《读Zepto源码之Touch模块》对 Touch 模块的分析。

parentIfText

function parentIfText(node){
  return 'tagName' in node ? node : node.parentNode
}

这个辅助方法是获取目标节点,如果节点不是元素节点,则用父节点作为目标节点。如果事件在文本节点或者伪类元素上触发时,会出现不是元素节点的情况。

事件

gesturestart

bind('gesturestart', function(e){
  var now = Date.now(), delta = now - (gesture.last || now)
  gesture.target = parentIfText(e.target)
  gestureTimeout && clearTimeout(gestureTimeout)
  gesture.e1 = e.scale
  gesture.last = now
})

Touch 模块一样,在 gesturestart 时,也用 delta 来记录两次 start 之间的时间间隔,用 gesture.target 来保存目标元素,e1 是起点时的缩放值。

gesturechange

bind('gesturechange', function(e){
  gesture.e2 = e.scale
})

gesturechange 时,更新终点 guesture.e2 的缩放值。

gestureend

if (gesture.e2 > 0) {
  Math.abs(gesture.e1 - gesture.e2) != 0 && $(gesture.target).trigger('pinch') &&
    $(gesture.target).trigger('pinch' + (gesture.e1 - gesture.e2 > 0 ? 'In' : 'Out'))
  gesture.e1 = gesture.e2 = gesture.last = 0
} else if ('last' in gesture) {
  gesture = {}
}

如果 gesture.e2 存在(不可能有小于 0 的情况吧?),在起点的缩放值和终点的缩放值不相同的情况下,触发 pinch 事件;如果起点的缩放值比终点的缩放值大,则继续触发 pinchIn 事件,则缩小效果;如果起点的缩放值比终点的缩放值小,则继续触发 pinchOut 事件,即放大效果。

最终将 e1e2last 都设置为 0

last 不存在的情况下(在调用 preventDefault 时),将 gesture 清空。

系列文章

  1. 读Zepto源码之代码结构
  2. 读Zepto源码之内部方法
  3. 读Zepto源码之工具函数
  4. 读Zepto源码之神奇的$
  5. 读Zepto源码之集合操作
  6. 读Zepto源码之集合元素查找
  7. 读Zepto源码之操作DOM
  8. 读Zepto源码之样式操作
  9. 读Zepto源码之属性操作
  10. 读Zepto源码之Event模块
  11. 读Zepto源码之IE模块
  12. 读Zepto源码之Callbacks模块
  13. 读Zepto源码之Deferred模块
  14. 读Zepto源码之Ajax模块
  15. 读Zepto源码之Assets模块
  16. 读Zepto源码之Selector模块
  17. 读Zepto源码之Touch模块

参考

License

署名-非商业性使用-禁止演绎 4.0 国际 (CC BY-NC-ND 4.0)

作者:对角另一面

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏十月梦想

一天带你入门到放弃vue.js(二)

至此在vue中提供了计算属性,computed,在main.js指定computed对象中指定计算

572
来自专栏高爽的专栏

Flex事件机制(二)

上一篇简单的介绍了Flex的事件机制以及处理事件的四种方式,本篇的主要内容是利用自定义事件在父子组件之间传递数据。        在Flex开发中,很多时候需...

1830
来自专栏偏前端工程师的驿站

实现滑动分页(微博分页方式)

  现在大家都在上微博,而微博的滑动分页引起了我的兴趣,于是自己模仿着做,以下是这段时间的成果(单纯实现,没有考虑到效率和其他细节问题)   实现内容:以30条...

1709
来自专栏大数据钻研

前端面试那些坑

HTML Doctype作用?严格模式与混杂模式如何区分?它们有何意义? HTML5 为什么只需要写 ? 行内元素有哪些?块级元素有哪些? 空(void)元素有...

3136
来自专栏前端小作坊

React diff 算法

React是facebook开发的一个用于UI开发的基础库。它自底向上重新设计了,为了实现高性能。在这篇文章中将展示React的diff算法是如何来优化你的ap...

903
来自专栏技术墨客

React Forwarding高阶组件传递Refs

通常情况下,我们想获取一个组建或则一个HTML元素的实例通过 Ref特性 就可以实现,但是某些时候我们需要在子父级组建中传递使用实例,Forwarding Re...

824
来自专栏互联网杂技

前端各种优化

1.  请减少HTTP请求   基本原理:   在浏览器(客户端)和服务器发生通信时,就已经消耗了大量的时间,尤其是在网络情况比较糟糕的时候,这个问题尤其的突...

3158
来自专栏崔庆才的专栏

Javascript - 事件顺序

1255
来自专栏向前进

【整合】input标签JS改变Value事件处理方法

  某人需要在时间控件给文本框赋值时,触发事件函数。实现的效果:   1、文本框支持手工输入,通过用户输入修改值,手工输入结束后触发事件。阻塞在于失去焦点后才触...

3405
来自专栏玄魂工作室

[翻译]整合鼠标、触摸 和触控笔事件的

Html5 Pointer Event Api 原文链接 https://mobiforge.com/design-development/html5-poin...

3176

扫码关注云+社区