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;
  }



相关文章
|
6天前
|
Web App开发 监控 JavaScript
监控和分析 JavaScript 内存使用情况
【10月更文挑战第30天】通过使用上述的浏览器开发者工具、性能分析工具和内存泄漏检测工具,可以有效地监控和分析JavaScript内存使用情况,及时发现和解决内存泄漏、过度内存消耗等问题,从而提高JavaScript应用程序的性能和稳定性。在实际开发中,可以根据具体的需求和场景选择合适的工具和方法来进行内存监控和分析。
|
2天前
|
运维 监控 JavaScript
鸿蒙next版开发:分析JS Crash(进程崩溃)
在HarmonyOS 5.0中,JS Crash指未处理的JavaScript异常导致应用意外退出。本文详细介绍如何分析JS Crash,包括异常捕获、日志分析和典型案例,帮助开发者定位问题、修复错误,提升应用稳定性。通过DevEco Studio收集日志,结合HiChecker工具,有效解决JS Crash问题。
17 4
|
11天前
|
Web App开发 JavaScript 前端开发
使用 Chrome 浏览器的内存分析工具来检测 JavaScript 中的内存泄漏
【10月更文挑战第25天】利用 Chrome 浏览器的内存分析工具,可以较为准确地检测 JavaScript 中的内存泄漏问题,并帮助我们找出潜在的泄漏点,以便采取相应的解决措施。
86 9
|
9天前
|
JavaScript 前端开发 开发者
前端框架对比:Vue.js与Angular的优劣分析与选择建议
【10月更文挑战第27天】在前端开发领域,Vue.js和Angular是两个备受瞩目的框架。本文对比了两者的优劣,Vue.js以轻量级和易上手著称,适合快速开发小型到中型项目;Angular则由Google支持,功能全面,适合大型企业级应用。选择时需考虑项目需求、团队熟悉度和长期维护等因素。
15 1
|
1月前
|
数据采集 JSON 前端开发
JavaScript逆向爬虫实战分析
JavaScript逆向爬虫实战分析
|
10天前
|
JavaScript 前端开发 API
前端框架对比:Vue.js与Angular的优劣分析与选择建议
【10月更文挑战第26天】前端技术的飞速发展让开发者在构建用户界面时有了更多选择。本文对比了Vue.js和Angular两大框架,介绍了它们的特点和优劣,并给出了在实际项目中如何选择的建议。Vue.js轻量级、易上手,适合小型项目;Angular结构化、功能强大,适合大型项目。
12 0
|
1月前
|
前端开发 JavaScript
JavaScript动态渲染页面爬取——CSS位置偏移反爬案例分析与爬取实战
JavaScript动态渲染页面爬取——CSS位置偏移反爬案例分析与爬取实战
|
4月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp小程序的数据分析岗位招聘信息与分析附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp小程序的数据分析岗位招聘信息与分析附带文章源码部署视频讲解等
21 0
|
4月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp小程序的高校成绩分析附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp小程序的高校成绩分析附带文章源码部署视频讲解等
37 0
|
4月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp小程序的学生成绩分析和弱项辅助系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp小程序的学生成绩分析和弱项辅助系统附带文章源码部署视频讲解等
39 0
下一篇
无影云桌面