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 來進行設備偵測,裏面是一大堆正則表達式,所以這個模塊後面是不打算分析的了。
然後是監測 gesturestart 、gesturechange、 gestureend 事件,根據這三個事件,可以組合出 pinch 、pinchIn 和 pinchOut 事件。其實就是縮小和放大的手勢操作。
其中變量 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 事件,即放大效果。
最終將 e1 、 e2 和 last 都設置為 0 。
在 last 不存在的情況下(在調用 preventDefault 時),將 gesture 清空。
系列文章
- 讀Zepto源碼之代碼結構
- 讀Zepto源碼之內部方法
- 讀Zepto源碼之工具函數
- 讀Zepto源碼之神奇的$
- 讀Zepto源碼之集合操作
- 讀Zepto源碼之集合元素查找
- 讀Zepto源碼之操作DOM
- 讀Zepto源碼之樣式操作
- 讀Zepto源碼之屬性操作
- 讀Zepto源碼之Event模塊
- 讀Zepto源碼之IE模塊
- 讀Zepto源碼之Callbacks模塊
- 讀Zepto源碼之Deferred模塊
- 讀Zepto源碼之Ajax模塊
- 讀Zepto源碼之Assets模塊
- 讀Zepto源碼之Selector模塊
- 讀Zepto源碼之Touch模塊
參考
- 指尖下的js —— 多觸式web前端開發之三:處理複雜手勢
License
署名-非商業性使用-禁止演繹 4.0 國際 (CC BY-NC-ND 4.0)
最後,所有文章都會同步發送到微信公眾號上,歡迎關注,歡迎提意見:
作者:對角另一面