原文:Delegated Events and Gestures in Ext JS 5

简介

Ext JS在5之前的版本,被设计为专用于传统鼠标输入的桌面设备使用。而从5开始,添加了对触屏输入的支持,这让Ext JS对设备的选择有了更大余地,包括主流的平板,以及触屏的笔记本电脑。这种变化会对使用框架的用户造成影响,但这有助于理解屏幕后的情况。在本文,将探讨框架是如何处理触碰事件以及在设备之间是如何实现事件的规范化。

Ext JS中的手势

也许,在Ext JS 5的事件系统中,最令人兴奋的莫过于添加了手势事件。由于Sencha Touch事件系统是形成Ext JS 5事件系统的基础,因而,对于Sencha Touch用户会发现他们对这些手势已经是相当熟悉了。而对于新手来说,手势是从底层浏览器事件合成的事件,例如,drag(拖)、swipe(滑动)、longpress(长按)、pinch(捏)和rotate(旋转)和tap(触碰)。Ext JS 5在未来会进一步采用触碰手势,并允许他们采用鼠标输入之外的触碰输入,或者在多输入设备的情况下采用两种输入。

从浏览器的角度来看,当一个页面的使用鼠标或触屏进行交互的时候,会触发3个基本事件(start(开始)、move(移动)和end(结束))。框架会监控这三个事件的次序和时序,以便确定是触发的是哪一种手势。

浏览器

Start

Move

End

桌面浏览器

mousedown

mousemove

mouseup

移动Webkit

touchstart

touchmove

touchend

IE10

MSPointerDown

MSPointerMove

MSPointerUp

IE11

pointerdown

pointermove

pointerup

当框架确定已经触发了一种手势的时候,它会将手势事件分发到任何正在监听事件的元素。监听手势事件与监听任何DOM事件没有任何区别,例如:

myElement.on('drag', myFunction);

以下的“单一触碰”手势可在所有支持跨平台的设备和浏览器上工作,而不需要理会它使用的输入设备是什么(鼠标或触碰):

手势

事件

Tap

tap, tapcancel

DoubleTap

singletap, doubletap

LongPress

longpress

Drag

dragstart, drag, dragend, dragcancel

Swipe

swipe, swipestart, swipecancel

EdgeSwipe

edgeswipestart, edgeswipe, edgeswipecancel

以下的“多点触碰”手势可在所有支持启用触碰的浏览器上工作,而这些浏览器需运行在带有触碰屏幕的设备上:

手势

事件

Pinch

pinchstart, pinch, pinchend, pinchcancel

Rotate

rotatestart, rotate, rotateend, rotatecancel

委托事件模型

Ext JS 5事件系统会直接将绑定的DOM监听通过一个不易察觉的但重要的范式转换为委托事件模型。这意味着对于每个事件类型(mousedown、touchstart等等),会在DOM层次结构的非常高的顶层(window对象)绑定一个单一的监听。当一个DOM元素触发了一个事件,事件会在被处理之前一直冒泡到顶层。在内部,这会让事情变得有那么一点点复杂,因为事件系统必须通过从目标元素开始遍历DOM层次结构来模拟事件传播,如果需要,还要在这个过程中调度事件处理程序。虽然看上去,这种方法会让事情毫无必要的复杂化,但它有以下几个重要优点:

  1. 委托事件模型是识别一种手势事件触发的关键。事件系统不断的监视某些关键事件的时机和次序,以便确定是否某一支持的手势已经发生。然后它可无缝的以正确次序将手势事件和本地事件合成在一起进行调度。
  2. 它极大的降低了DOM监听的绑定,从而改善内存的使用状态,而且去除了DOM监听的单点数量。这对于减少在旧的浏览器中的内存泄漏方面很有可能获得额外的收益,因为这简化了窗口卸载时的清理工作。
  3. 它允许在旧的浏览器中“自上而下”(捕获)的事件传播。因为IE8不支持addEventListener方法和useCapture选项,直接绑定的DOM事件只支持使用自底往上的冒泡模型进行传播。委托事件模型通过使用它自己的人工传播模式实现了“冒泡”和“捕获”的传播,从而解决了这个问题。用户在绑定事件时,可通过简单的传递capture选项来绑定捕获监听,而事件处理程序将按自上而下的顺序跨所有浏览器和设备进行派生。例如:
myElement.on({
click: someFunction,
capture: true
});

使用委托模型的潜在挑战

对于框架来说,任何根本性的改变意味着可能会与现有的代码的不兼容,这是因为它涉及到新的事件系统,而现有的代码通常会被分为两个阵营:

  1. 只使用Ext JS事件系统API来绑定事件监听的应用程序代码,如Ext.Element#addListener()或Ext.Element#on() 会幸福的感觉到没有变化。如果应用程序代码只使用了Ext JS API来绑定监听,那么新的事件系统将被设计为100%向后兼容Ext JS 4的事件系统。
  2. 混合了符合Ext JS与其他JavaScript的库的应用程序代码,又或者是使用了DOM API来直接绑定事件到元素的代码要切换到委托事件系统可能会负面影响。出现这种情况是因为直接绑定事件处理程序的时机在当前情况下与同时使用委托的时机是不同的。如果应用程序代码预期事件处理会以一个指定顺序执行,就会出现问题,不过,在事件处理尝试去停止给定事件的人工传播时,这可能会变得更明显。
  1. 委托监听可以调用stopPropagation方法,并停止委托事件的系统模拟传播,不过,这也会阻止任何直接绑定的监听事件的触发,这是因为在委托监听在进行处理的时候,对于直接绑定监听的事件触发来说,这太迟了,这时候,本地事件已经冒泡到DOM的顶层了。
  2. 如果直接绑定的DOM监听调用stopPropagation方法,它会阻止所以委托监听的除非,包括那些在DOM内它下面的元素,造成这种情况是因为在直接绑定事件中调用stopPropagation方法会阻止本地事件冒泡到顶部,从而阻止了通过委托事件系统对它进行处理。而这,有可能造成禁用手势识别,因为手势是在DOM的顶层进行处理的。

如果处于某种原因,觉得委托模型是不受欢迎的,可以在 listeners中使用一个简单的标识来取消该选项:

myElement.on({
click: myFunction,
delegated: false
});

不过,在取消使用委托事件模型的时候一定要谨慎,因为对于直接绑定DOM监听,它可能会产生同样的负面影响(如前文所述),尤其是在涉及stopPropagation的时候。

事件规范化

新的事件系统的主要目标之一就是使现有的Ext JS应用程序(升级应用程序的工作量很少或没有)可以在平板或触屏笔记本电脑上运行。未来实现这个目标,框架会在后台进行一些基本的事件规范化工作。当监听到一个鼠标事件的时候,如mousedown或click,框架实际上会绑定一个类似的touch事件或pointer事件(如果设备支持此类事件)。例如,如果应用程序尝试绑定一个mousedown监听:

myElement.on('mousedown', someFunction);

在移动版Safari,事件系统会转化为:

myElement.on('touchstart', someFunction);

然而,在IE11上,会转化为:

myElement.on('pointerdown', someFunction);

译者注:微软这变态,又搞一套自己的东西

这样就使触碰屏幕的交互与鼠标交互在大多少情况下行为是相同。

当在触屏设备上运行的时候,以下鼠标事件会直接转换为触碰或指针事件:

  • mousedown -> touchstart or pointerdown
  • mousemove -> touchmove or pointermove
  • mouseup -> touchend or pointerup
  • click -> tap
  • dblclick -> doubletap

不过,对于一些鼠标事件,在触碰世界并没有适合的模拟事件。如果应用程序依赖于以下任何事件,则需要由开发人员来决定在使用触屏输入时是否或如何来实现:

  • mouseover
  • mouseout
  • mouseenter
  • mouseleave

虽然事件规范化对于大多数应用程序来说相当不错,但也存在需要取消的情况。在Ext JS 5提供了translate事件选项来实现这个:

myElement.on({
mousedown: myFunction,
translate: false
});

设置translate选项为false就可阻止事件系统对这个监听进行事件规范化,因此,事件处理只会在真正的mousedown发生时才会执行。

小结

Ext JS一直是HTML 5桌面应用程序的首先框架,但现在桌面和移动之间的界限变得越来越模糊,因而,使用了手势和事件规范化的新的Ext JS 5事件系统,可以让Ext JS在传统的桌面设备上和启用了触碰模式的设备和浏览器上继续保持领先。

作者:Phil Guerrant
Phil is a Sencha software engineer who works on Ext JS. He has over 10 years of experience as a developer and specializes in HTML5 and web development, UI, and agile methodologies.

【翻译】Ext JS 5的委托事件和手势的更多相关文章

  1. 【转载】《Ext JS 4 First Look》翻译之一:新特性

    免责声明:     本文转自网络文章,转载此文章仅为个人收藏,分享知识,如有侵权,请联系博主进行删除.     原文作者:^_^肥仔John      原文地址:http://www.cnblogs. ...

  2. 【翻译】Sencha Ext JS 5公布

    原文:Announcing Sencha Ext JS 5 简单介绍 我代表Sencha和整个Ext JS团队,非常自豪的宣布,在今天,Sencha Ext JS 5公布了.Ext JS 5已经迈出了 ...

  3. 【翻译】Ext JS 6 Beta发布

    原文:Ext JS 6 Beta is Now Available 概述 Ext JS 6的好处 新的Ext JS功能和工具 需要你的反馈意见 概述 很高兴,Ext JS 6 beta版本现在发布了. ...

  4. 【翻译】Ext JS 5的平板支持

    原文:Ext JS 5 Tablet Support Ext JS已被公认为桌面Web应用程序的领先框架.自从平板开始在全球挑战PC的销售,无论是个人还是企业,电脑横向的应用已经产生急剧的变化.Sen ...

  5. 【翻译】Sencha Ext JS 5发布

    原文:Announcing Sencha Ext JS 5 简介 我代表Sencha和整个Ext JS团队,很自豪的宣布,在今天,Sencha Ext JS 5发布了.Ext JS 5已经迈出了一大步 ...

  6. Ext JS 5的声明式事件监听

    在前文<在Ext JS 5使用ViewControllers>中,简单的介绍了Ext JS 5的一项重要改进——声明式事件监听.在本文,将深度探讨如何使用声明式事件监听啦简化应用程序的视图 ...

  7. Ext JS treegrid 发生的在tree上增加itemclick 与在其它列上增加actioncolumn 发生事件冲突(event conflict)的解决办法

    Ext JS treegrid 发生的在tree上增加itemclick 与在其它列上增加actioncolumn 发生事件冲突(event conflict)的解决办法 最近在适用Ext JS4开发 ...

  8. 【翻译】在Ext JS 5种使用ViewControllers

    原文:Using ViewControllers in Ext JS 5 简单介绍 在Ext JS 5中,在应用程序架构方面提供了一些令人兴奋的改进,如加入了ViewModels.MVVM以及view ...

  9. 【翻译】探究Ext JS 5和Sencha Touch的布局系统

    原文:Exploring the Layout System in Ext JS 5 and Sencha Touch 布局系统是Sencha框架中最强大和最有特色的一个部分. 布局要处理应用程序中每 ...

随机推荐

  1. Docker常见仓库Redis

    Redis 基本信息 Redis 是开源的内存 Key-Value 数据库实现. 该仓库提供了 Redis 2.6 ~ 2.8.9 各个版本的镜像. 使用方法 默认会在 6379 端口启动数据库. $ ...

  2. Python3 解释器

    Linux/Unix的系统上,Python解释器通常被安装在 /usr/local/bin/python3.4 这样的有效路径(目录)里. 我们可以将路径 /usr/local/bin 添加到您的Li ...

  3. Linux 下的一个全新的性能测量和调式诊断工具 Systemtap,第 1 部分: kprobe

    kprobe 的原理.编程接口.局限性和使用注意事项 本系列文章详细地介绍了一个Linux下的全新的调式.诊断和性能测量工具Systemtap和它所依赖的基础kprobe以及促使开发该工具的先驱DTr ...

  4. Android简易实战教程--第三十九话《简单的模糊查询》

    今天这一篇小案例模拟模糊查询,即输入一个字符,显示手机对应的所有存在该字符的路径. 布局: <?xml version="1.0" encoding="utf-8& ...

  5. android studio 转为eclipse快捷键后还存在的问题汇总

    提取局部变量:Ctrl+Alt+V 提取全局变量:Ctrl+Alt+F 提取方法:Shit+Alt+M 使用android studio 出现红色下划线代表有错误产生,eclipse中的Ctrl+1( ...

  6. java 随机数高效生成

    分享牛,分享牛原创.近期去面试经常被问到java如何生产随机数,以及生成很大的字符串保证不能重复,还要考虑性能,之前本人面试别人的时候,可能不会问这个问题.既然这个java随机数问题经常被问到,那咱们 ...

  7. [ExtJS5学习笔记]第三十六节 报表组件mzPivotGrid

    mzPivotGrid 是一个报表组件,采用这个组件之后,可以令你的应用体现更多的价值. 什么是pivot grid 什么是mzPivotGrid 学习资源 与图表组件的融合 什么是pivot gri ...

  8. UISearchController替换UISearchDisplayController

    随着iOS 的升级,iOS 7的占有率更低了.Xcode 升级到Xcode 8之后,对iOS 应用支持的最低版本,iOS 7也被抛弃了.我在新项目中也是最低支持到iOS 8,因此工程里也是各种警告.首 ...

  9. 使用OpenCV读、操作、写图像并与bash合作对某个目录下所有图像进行类似处理

    我门要对某个目录下所有图像文件进行统一处理,如果图像的数量过多,那么手动地一张张处理就会显得有些麻烦.本文使用OpenCV和bash来完成我们指定的任务. 任务 将目录A下的所有统一格式的jpg图像变 ...

  10. 在Debian/Ubuntu系统中安装*.sh与*.bin文件

    在Debian/Ubuntu系统中安装*.sh与*.bin文件的基本方法.一,安装*.sh文件运行命令行至文件目录下,执行:sudo sh *.sh直接运行在命令行中执行:sudo chmod +x ...