Hammer.js分析(一)——基礎結構

愛雨星威 8年前發布 | 32K 次閱讀 WebKit JavaScript開發

來自: http://www.cnblogs.com/strick/p/5173576.html

github 上面將源碼下載下來,會發現有個src文件夾。當前版本是2.0.6。

總的結構如下:

一、常量

這里將常量全部列在一起是可以在對比源碼的時候,更方便的查看相應內容。

var VENDOR_PREFIXES = ['', 'webkit', 'Moz', 'MS', 'ms', 'o'];//前綴
var TEST_ELEMENT = document.createElement('div');//測試元素
var TYPE_FUNCTION = 'function';//函數

//----------------------------Input---------------------------------------- var MOBILE_REGEX = /mobile|tablet|ip(ad|hone|od)|android/i;//判斷移動端的正則

var SUPPORT_TOUCH = ('ontouchstart' in window);//判斷是否支持touch事件 var SUPPORT_POINTER_EVENTS = prefixed(window, 'PointerEvent') !== undefined;//判斷是否支持指針事件 var SUPPORT_ONLY_TOUCH = SUPPORT_TOUCH && MOBILE_REGEX.test(navigator.userAgent);//判斷是觸屏

var INPUT_TYPE_TOUCH = 'touch'; var INPUT_TYPE_PEN = 'pen'; var INPUT_TYPE_MOUSE = 'mouse'; var INPUT_TYPE_KINECT = 'kinect';

var COMPUTE_INTERVAL = 25;

var INPUT_START = 1;//1 2 4 8 16方便使用"與"跟"或"判斷 var INPUT_MOVE = 2; var INPUT_END = 4; var INPUT_CANCEL = 8;

var DIRECTION_NONE = 1; var DIRECTION_LEFT = 2; var DIRECTION_RIGHT = 4; var DIRECTION_UP = 8; var DIRECTION_DOWN = 16;

var DIRECTION_HORIZONTAL = DIRECTION_LEFT | DIRECTION_RIGHT; var DIRECTION_VERTICAL = DIRECTION_UP | DIRECTION_DOWN; var DIRECTION_ALL = DIRECTION_HORIZONTAL | DIRECTION_VERTICAL;

var PROPS_XY = ['x', 'y']; var PROPS_CLIENT_XY = ['clientX', 'clientY'];

var MOUSE_ELEMENT_EVENTS = 'mousedown'; var MOUSE_WINDOW_EVENTS = 'mousemove mouseup';

var POINTER_ELEMENT_EVENTS = 'pointerdown'; var POINTER_WINDOW_EVENTS = 'pointermove pointerup pointercancel';

var SINGLE_TOUCH_TARGET_EVENTS = 'touchstart'; var SINGLE_TOUCH_WINDOW_EVENTS = 'touchstart touchmove touchend touchcancel';

var TOUCH_TARGET_EVENTS = 'touchstart touchmove touchend touchcancel';

//----------------------------TouchAction---------------------------------------- var PREFIXED_TOUCH_ACTION = prefixed(TEST_ELEMENT.style, 'touchAction'); var NATIVE_TOUCH_ACTION = PREFIXED_TOUCH_ACTION !== undefined;

// magical touchAction value var TOUCH_ACTION_COMPUTE = 'compute'; var TOUCH_ACTION_AUTO = 'auto'; var TOUCH_ACTION_MANIPULATION = 'manipulation'; // not implemented var TOUCH_ACTION_NONE = 'none'; var TOUCH_ACTION_PAN_X = 'pan-x'; var TOUCH_ACTION_PAN_Y = 'pan-y';

//----------------------------Recognizer---------------------------------------- var STATE_POSSIBLE = 1; var STATE_BEGAN = 2; var STATE_CHANGED = 4; var STATE_ENDED = 8; var STATE_RECOGNIZED = STATE_ENDED;//已完成recognize var STATE_CANCELLED = 16; var STATE_FAILED = 32;

//----------------------------Manager---------------------------------------- var STOP = 1; var FORCED_STOP = 2;</pre>

二、utils.js

各種工具方法包含其中。

1)setTimeoutContext:封裝了一下setTimeout

2)invokeArrayArg:遍歷數組對象,并執行其中的某個方法

3)each:遍歷一個object對象或數組

4)deprecate:過時警告與棧追蹤

5)assign:拷貝對象,target中的屬性將會覆蓋source中的屬性。目標ES6中新增了一個 Object.assign() 特性

6)extend:用一個或多個其他對象來擴展一個對象,有個bool值“merge”控制是否會覆蓋屬性

7)merge:合并對象,dest中的屬性將不會覆蓋src中的屬性

8)inherit:簡單的類繼承方法

9)bindFn:指定作用域執行函數

10)boolOrFn:傳遞函數就執行函數,傳遞布爾值就返回boolean

11)ifUndefined:傳遞兩個值,第一個值是undefined就返回第二個值,否則返回第一值

12)addEventListeners:封裝了addEventListener方法,可通過空格綁定多個事件

13)removeEventListeners:移除綁定的事件

14)hasParent:判斷是否有父級元素,返回boolean

15)splitStr:根據空格分割字符串,返回Array

16)inStr:判斷某個字符串是否被包含,返回boolean

17)inArray:查找某個值在數組中的位置值,返回int

18)toArray:通過“Array.prototype.slice.call”將對象轉換成數組

19)uniqueArray:數組去重,返回Array

20)prefixed:獲取加了前綴的屬性,沒有則返回undefined,前綴包括['', 'webkit', 'Moz', 'MS', 'ms', 'o']

21)uniqueId:獲取唯一值,比較簡單就是一個遞增的數,返回int

22)getWindowForElement:獲取元素的窗口對象

三、hammer.js

1)Hammer方式初始化,帶預置“Recognizer”(識別器)數組

插件的使用方法是先創建一個Hammer對象,代碼如下:

var layer = document.getElementById('layer');
var mc = new Hammer(layer);

當new的時候,函數內部其實是初始化了一個Manager對象(上面的manager.js),并初始化默認參數defaults。

function Hammer(element, options) {
    options = options || {};
    options.recognizers = ifUndefined(options.recognizers, Hammer.defaults.preset);
    return new Manager(element, options);
}

“ Hammer.defaults . preset ”是一個“Recognizer”(識別器)對象數組。

可以讓Manager對象預先安裝tap、doubletap、 pan、 swipe、press、 pinch和rotate識別器。

preset: [
        // RecognizerClass, options, [recognizeWith, ...], [requireFailure, ...]
        [RotateRecognizer, {enable: false}],
        [PinchRecognizer, {enable: false}, ['rotate']],
        [SwipeRecognizer, {direction: DIRECTION_HORIZONTAL}],
        [PanRecognizer, {direction: DIRECTION_HORIZONTAL}, ['swipe']],
        [TapRecognizer],
        [TapRecognizer, {event: 'doubletap', taps: 2}, ['tap']],
        [PressRecognizer]
]

2)Manager方式初始化,不帶預置

如果不做上面的識別器預置操作,就需要手動添加相應的識別器對象,例如下面的“Tap”。

var mc = new Hammer.Manager(layer);
mc.add(new Hammer.Tap());

關于 manager.js 的詳細說明將會在下一篇文章做討論。

3)expose.js

在上一段代碼中,之所以能夠引用“Hammer.Tap”,就是因為這段代碼中做了拷貝。

assign(Hammer, {
  Tap: TapRecognizer,
  Pan: PanRecognizer,
  Swipe: SwipeRecognizer,
  //...省略其他值
});

除了拷貝,剩下的代碼做模塊化聲明、全局賦值等。

四、touchaction.js

模擬CSS中的一個屬性“ touch-action ”,這個屬性兼容性非常差,目前只有Chrome 35+, IE10+支持。

1)演示

在“ Hammer.defaults ”默認參數中有一個“ touchAction ”屬性,這個值可以阻止滾動。用手機掃描下面的二維碼體驗下這個屬性:

我用UC瀏覽器打開了這個demo操作頁面,滑動到“pan-y”處左右滑動屏幕,頁面不會出現左右拖動的情況。在“pan-x”處,上下滑動,屏幕不會跟著滾動。

這個屬性非常有用,比如圖片滾動展示, 你要看下一張圖,那就得用手指劃,如果整個頁面跟著劃過去,那體驗很不好,還可能導致誤操作。

下面的表格是描述設置哪個值比較適合對應的手勢操作:

2)update

在很多地方都會引用到“this.touchAction.update()”,這個方法里面引用了對象中的另外一個方法“set”。

update: function() {
    this.set(this.manager.options.touchAction);
}
var PREFIXED_TOUCH_ACTION = prefixed(TEST_ELEMENT.style, 'touchAction');
var NATIVE_TOUCH_ACTION = PREFIXED_TOUCH_ACTION !== undefined;
set: function(value) {
  // 自己做計算
  if (value == TOUCH_ACTION_COMPUTE) {
    value = this.compute();
  }
  //支持原生"touch-action"就直接賦值
  if (NATIVE_TOUCH_ACTION && this.manager.element.style) {
    this.manager.element.style[PREFIXED_TOUCH_ACTION] = value;
  }
  this.actions = value.toLowerCase().trim();//緩存屬性值,用于后面的polyfill
}

五、操作流程圖

var layer = document.getElementById('layer');
var mc = new Hammer.Manager(layer);
mc.add(new Hammer.Tap());

mc.on('tap', function(e) { layer.style.display = "none"; e.preventDefault(); });</pre>

初始化的流程在 下一篇文章 會有介紹。這里就講一個點擊操作的流程,其中綠色框中的內部邏輯不同操作會各有不同:

最后一步中handlers中保存的事件就是 mc.on 中的內容。

demo源碼下載:

http://download.csdn.net/download/loneleaf1/9429375

參考資料:

http://tech.gilt.com/2014/09/23/five-things-you-need-to-know-about-hammer-js-2-0/

FIVE THINGS YOU NEED TO KNOW ABOUT HAMMER.JS 2.0

http://www.cnblogs.com/iamlilinfeng/p/4239957.html Hammer.js

http://colinued.leanote.com/post/%E7%A7%BB%E5%8A%A8%E7%AB%AF%E6%89%8B%E5%8A%BF%E5%BA%93hammerJS-2.0.4%E5%AE%98%E6%96%B9%E6%96%87%E6%A1%A3%E7%BF%BB%E8%AF%91 移動端手勢庫hammerJS-2.0.4

</div>

 本文由用戶 愛雨星威 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!