Hammer.js分析(一)——基础结构

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;

二、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();
});

初始化的流程在下一篇文章会有介绍。这里就讲一个点击操作的流程,其中绿色框中的内部逻辑不同操作会各有不同:

最后一步中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

时间: 2024-12-22 06:37:47

Hammer.js分析(一)——基础结构的相关文章

Hammer.js分析(二)——manager.js

“Manager”是所有识别器实例的容器,它为你设置的元素安装了交互事件监听器,并设置了触摸事件特性. manager.js中的代码会涉及到input.js和recoginzer.js中的内容,这里会先做大致的流程分析,具体分析会在接下来的文章中详谈. 一.Manager构造函数 初始化流程如下所示: 对应的函数代码如下所示: function Manager(element, options) { this.options = assign({}, Hammer.defaults, optio

Hammer.js分析(三)——input.js

input.js是所有input文件夹中类的父类,浏览器事件绑定.初始化特定的input类.各种参数计算函数. Input父类和其子类就是在做绑定事件,各种参数计算.整合.设置等返回自定义事件对象,交给识别器的相关对象使用. 一.Input父类 Input相当于一个抽象类,对象中总共有3个方法 1)handler(ev) 这相当于一个抽象方法,在上图中的6个子对象里,都会实现这个方法. ev是事件对象(不是自定义的那个),例如触屏事件中就是 TouchEvent. 2)init()与destro

Hammer.js分析(四)——recognizer.js

不同识别器会使用不同逻辑,根据从相关Input类获取到的事件对象和事件,实现自定义的触屏事件,例如tap.pinch等. 一.继承关系 Recognizer与前面的Input一样,也相当于是个抽象类. 从上图中可以看到,6个子类都会先继承AttrRecognizer类,因为AttrRecognizer类中的2个方法可以共用,attrTest与process,如果自己不实现,就可以直接调用. 二.识别器状态 每个识别器的初始状态是 “POSSIBLE”,每个识别器都会有一个状态周期. 例如做一次

移动端手势事件 hammer.JS插件

一.引入hammer.JS 1.下载地址:http://download.csdn.net/detail/webxiaoma/9872249 2.官网地址:http://hammerjs.github.io/examples/ 3.CDN链接:http://hammerjs.github.io/dist/hammer.min.js 二.用法 1.首先我们先写一个出发事件的DOM元素 HTML: <style type="text/css"> html, body { wid

利用轮播原理结合hammer.js实现简洁的滑屏功能

最近有个任务,做一个非常小的h5的应用,只有2屏,需要做横向的全屏滑动切换和一些简单的动画效果,之前做这种东西用的是fullpage.js和jquery,性能不是很好,于是就想自己动手弄一个简单的东西来实现.最后我用zepto + hammer.js 和轮播的方式解决了这个问题,效果还不错,整个页面不开启Gzip时所有资源请求的数据大小为200KB左右.这篇文章总结下这个方法的实现思路. 效果演示(代码下载): 1. 实现要点 1)滑屏借鉴bootstrap的carousel插件,不过完全没有它

Hammer.js

一.前言 移动端框架当前还处在初级阶段,但相对于移动端的应用来说已经有很长时间了.虽然暂时还没有PC端开发的需求量大,但移动端的Web必然是一种趋势,在接触移动端脚本的过程中,最开始想到的是juqery.Jquery2.0版本及以上已经开始偏向移动端,如对h5的支持,但支持还是不够完善,希望jq在后面的版本能够逐渐支持起来. 最初在开发移动端Web的时候使用w3c标准的语法结构和原生的js开发,但相对来说开发量比较大,而且每一步都要考虑各移动端浏览器的兼容,像比较让程序员头痛的大wp手机,很多事

hammer.js初探

最近觉得自己的进步比较慢了,很有可能是因为中文区的学习和百度的使用极大的限制了自己的视野,所以,以后无论是新技术的学习,还是问题的解决,做到以下几点: 新技术的学习必须通过英文文档,而不是翻译过来的蹩脚的中文文档. 问题的搜寻通过google.通过stackoverflow,如果在知道其局限性的情况下再去百度或者其他方法. 遇到有问题的词汇就通过Google翻译搜寻,但实际上这时候通过百度也是可以的,因为百度知道的存在也是有用的. 嗯,第一个完整的英文文档就从hammer.js开始吧! 加油.

使用Hammer.js的H5页面开发DOM的一些小说法

前几天,一个小伙伴说叫我帮他写一个移动端上的一个轮播图,个人一般是不接私活的,毕竟平时工作也是单双休,时间也不很多. 可能大部分程序员,多余的时间都是看看新闻,打游戏,或者学习新的知识,缺少运动吧. 所以,个人感觉接私活那点时间,你可以去锻炼身体,或者学习新的知识,当然这些都是看法,完全不代表你跟我有一样的看法,好吧,不过既然是朋友,以前也是同学,而且不就是一个轮播图吗,自己也写过一些移动端里,轮播图是移动端上最常见的一个广告展示功能. 但是,当小伙伴把大致的需求高速了我以后,完全跟轮播图没有,

Hammer.js移动端触屏框架的使用

hammer.js是一个多点触摸手势库,能够为网页加入Tap.Double Tap.Swipe.Hold.Pinch.Drag等多点触摸事件,免去自己监听底层touchstart.touchmove.touchend事件并且写一大堆判断逻辑的痛苦.hammer.js不但支持触摸屏设备的浏览器,在桌面浏览器上,也能将鼠标的点击当做触摸,方便开发人员在桌面浏览器上调试.这是一个专为触摸手势而生的js库,对有需要的朋友非常有帮助,奉上常用的一些方法调用文档. 使用方法: 1 2 3 4 5 6 7 8