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

简介: 不同识别器会使用不同逻辑,根据从相关Input类获取到的事件对象和事件,实现自定义的触屏事件,例如tap、pinch等。

不同识别器会使用不同逻辑,根据从相关Input类获取到的事件对象和事件,实现自定义的触屏事件,例如tap、pinch等。


一、继承关系


35.jpg

Recognizer与前面的Input一样,也相当于是个抽象类。

从上图中可以看到,6个子类都会先继承AttrRecognizer类,因为AttrRecognizer类中的2个方法可以共用,attrTest与process,如果自己不实现,就可以直接调用。

 

二、识别器状态


每个识别器的初始状态是 “POSSIBLE”,每个识别器都会有一个状态周期。

例如做一次 “tap” 操作,浏览器使用了touch相关操作模拟: touchstart -> touchend,而状态是从 STATE_FAILED -> STATE_ENDED。

6种操作的状态走向图如下:


36.jpg


在 manage.js 中recognize方法,就是在根据识别器状态,来给 “curRecognizer” 与 “session.curRecognizer” 赋值,缓存这个当前周期内的状态。

如果识别器的状态是FAILED, CANCELLED 或者 RECOGNIZED (等同于 ENDED),那就要重置为 POSSIBLE,或结束当前识别器周期,让下一个识别器来。

下面的1,2,4,8等这样取值是为了方便位运算。


var STATE_POSSIBLE = 1;
var STATE_BEGAN = 2;
var STATE_CHANGED = 4;
var STATE_ENDED = 8;
var STATE_RECOGNIZED = STATE_ENDED;
var STATE_CANCELLED = 16;
var STATE_FAILED = 32;


三、Recognizer父类中的抽象方法


1. process(inputData)

返回识别器的状态,各个子类的实现逻辑都会不同,如果没有实现,就会引用通用父类AttrRecognizer中的process。

 

2. getTouchAction()

获取“touch-action”的属性数组


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';
getTouchAction: function() {
    return [TOUCH_ACTION_MANIPULATION];
}


3. reset()


只有 tap.js 与 press.js实现了这个方法


1 reset: function() {
2     clearTimeout(this._timer);
3 }


四、Recognizer父类中的方法


1)recognizeWith(otherRecognizer)  和 dropRecognizeWith(otherRecognizer)


recognizeWith:就是让当前识别器运行的时候同步运行所给的其它识别器(otherRecognizer),就是让几个操作同时触发,例如结合tap和rotate。

dropRecognizeWith:就是解除这层关系。


tap.recognizeWith(new Hammer.Rotate());


上面的代码中 recognizeWith 在内部会调用三次,下面的第17行代码,促使这个方法调用3次。


/**
 * @param {Recognizer|Array|String} otherRecognizer
 * @returns {Recognizer} this
 */
recognizeWith: function(otherRecognizer) {
  //支持一个识别器组成的数组来作为参数
  if (invokeArrayArg(otherRecognizer, 'recognizeWith', this)) {
    return this;
  }
  var simultaneous = this.simultaneous;
  //如果识别器被添加到了Manager上,也支持将其它识别器(otherRecognizer)的事件名(字符串形式)来作为参数
  otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
  if (!simultaneous[otherRecognizer.id]) {
    //保存到 simultaneous 数组中
    simultaneous[otherRecognizer.id] = otherRecognizer;
    otherRecognizer.recognizeWith(this);//调用otherRecognizer的方法
  }
  return this;
}

manager.js中recognize方法内调用了个 canRecognizeWith 的方法,里面其实就是在根据识别器的ID判断是否存在。

1 canRecognizeWith: function(otherRecognizer) {
2   return !!this.simultaneous[otherRecognizer.id];
3 }

2)requireFailure(otherRecognizer)  和 dropRequireFailure(otherRecognizer)


requireFailure:与recognizeWith相反,在某个操作的时候,不执行otherRecognizer。也就是只有当其它识别器(otherRecognizer)无效时才执行该识别器。

dropRequireFailure:解除这层关系。

/**
 * @param {Recognizer|Array|String} otherRecognizer
 * @returns {Recognizer} this
 */
requireFailure: function(otherRecognizer) {
  if (invokeArrayArg(otherRecognizer, 'requireFailure', this)) {
    return this;
  }
  var requireFail = this.requireFail;
  otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
  if (inArray(requireFail, otherRecognizer) === -1) {
    requireFail.push(otherRecognizer);//维护一个requireFail数组
    otherRecognizer.requireFailure(this);
  }
  return this;
}


这个 requireFail 数组在 Recognizer.canEmit 方法中会被调用,返回一个boolean值,用于在 Recognizer.tryEmit 是否能执行子类中的 emit 方法。

在第一篇《基础结构》的操作流程图中,有调用 emit 方法,子类是 Tap。


tryEmit: function(input) {
    if (this.canEmit()) {
      return this.emit(input);
    }
    // it's failing anyway
    this.state = STATE_FAILED;
  },
  canEmit: function() {
    var i = 0;
    while (i < this.requireFail.length) {
      if (!(this.requireFail[i].state & (STATE_FAILED | STATE_POSSIBLE))) {
        return false;
      }
      i++;
    }
    return true;
  }



相关文章
|
9天前
|
JavaScript 前端开发 安全
安全开发-JS应用&原生开发&JQuery库&Ajax技术&加密编码库&断点调试&逆向分析&元素属性操作
安全开发-JS应用&原生开发&JQuery库&Ajax技术&加密编码库&断点调试&逆向分析&元素属性操作
|
1天前
|
Web App开发 前端开发 JavaScript
技术心得记录:瀑布流的布局原理分析(纯CSS瀑布流与JS瀑布流)
技术心得记录:瀑布流的布局原理分析(纯CSS瀑布流与JS瀑布流)
|
27天前
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的高校智能培训管理系统分析与设计附带文章和源代码设计说明文档ppt
基于ssm+vue.js+uniapp小程序的高校智能培训管理系统分析与设计附带文章和源代码设计说明文档ppt
18 1
|
28天前
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的法律咨询系统的分析与设计附带文章和源代码设计说明文档ppt
基于ssm+vue.js+uniapp小程序的法律咨询系统的分析与设计附带文章和源代码设计说明文档ppt
19 1
|
21天前
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的电商数据分析附带文章和源代码部署视频讲解等
基于ssm+vue.js+uniapp小程序的电商数据分析附带文章和源代码部署视频讲解等
20 0
|
1月前
|
数据采集 JavaScript 数据可视化
Node.js爬虫在租房信息监测与分析中的应用
Node.js爬虫在租房信息监测与分析中的应用
|
1月前
|
JavaScript 前端开发 API
框架分析(3)-Vue.js
框架分析(3)-Vue.js
|
1月前
|
小程序 开发者
微信小程序“Error: xxx.js 已被代码依赖分析忽略,无法被其他模块引用”报错?
微信小程序“Error: xxx.js 已被代码依赖分析忽略,无法被其他模块引用”报错?
|
1月前
|
监控 JavaScript 安全
监控内网电脑软件设计与实现:基于Node.js的服务器端架构分析
在当今信息技术高度发达的时代,监控内网电脑的需求日益增长。企业需要确保网络安全,个人用户也需要监控家庭网络以保护隐私和安全。本文将介绍一种基于Node.js的服务器端架构,用于设计和实现监控内网电脑软件。
165 0
|
1月前
|
机器学习/深度学习 自然语言处理 JavaScript
GEE机器学习——最大熵分类器案例分析(JavaScript和python代码)
GEE机器学习——最大熵分类器案例分析(JavaScript和python代码)
70 0