讀Zepto原始碼之Gesture模組

對角另一面發表於2017-09-25

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)

最後,所有文章都會同步傳送到微信公眾號上,歡迎關注,歡迎提意見:

作者:對角另一面

相關文章