Gesture
模块基于 IOS
上的 Gesture
事件的封装,利用 scale
属性,封装出 pinch
系列事件。javascript
读 Zepto 源码系列文章已经放到了github上,欢迎star: reading-zeptohtml
本文阅读的源码为 zepto1.2.0前端
《reading-zepto》java
;(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
来进行设备侦测,里面是一大堆正则表达式,因此这个模块后面是不打算分析的了。node
而后是监测 gesturestart
、gesturechange
、 gestureend
事件,根据这三个事件,能够组合出 pinch
、pinchIn
和 pinchOut
事件。其实就是缩小和放大的手势操做。ios
其中变量 gesture
对象和 Touch
模块中的 touch
对象的做用差很少,能够先看看 《读Zepto源码之Touch模块》对 Touch
模块的分析。git
function parentIfText(node){
return 'tagName' in node ? node : node.parentNode
}复制代码
这个辅助方法是获取目标节点,若是节点不是元素节点,则用父节点做为目标节点。若是事件在文本节点或者伪类元素上触发时,会出现不是元素节点的状况。github
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
是起点时的缩放值。web
bind('gesturechange', function(e){
gesture.e2 = e.scale
})复制代码
在 gesturechange
时,更新终点 guesture.e2
的缩放值。正则表达式
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
事件,即放大效果。
最终将 e1
、 e2
和 last
都设置为 0
。
在 last
不存在的状况下(在调用 preventDefault
时),将 gesture
清空。
署名-非商业性使用-禁止演绎 4.0 国际 (CC BY-NC-ND 4.0)
最后,全部文章都会同步发送到微信公众号上,欢迎关注,欢迎提意见:
做者:对角另外一面