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)
最後,全部文章都會同步發送到微信公衆號上,歡迎關注,歡迎提意見:
做者:對角另外一面