原文: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. PHP 字符串变量

    PHP 字符串变量 字符串变量用于存储并处理文本. PHP 中的字符串变量 字符串变量用于包含有字符的值. 在创建字符串之后,我们就可以对它进行操作了.您可以直接在函数中使用字符串,或者把它存储在变量 ...

  2. PHP MySQL Where 子句

    WHERE 子句 WHERE 子句用于提取满足指定标准的的记录. 语法 SELECT column_name(s) FROM table_name WHERE column_name operator ...

  3. C语言完美体系

    **第 1 篇 C 语言第一阶段 13 1.1C 语言第一阶段--语言课程概述 13 1.1.1 什么是语言,什么是 C 语言 13 1.1.2 基本常识 14 1.1.3 人与计算机之间的更好的交互 ...

  4. 开机小脚本自动打开sublime text 和git-bash

    set subl="C:\Program Files (x86)\Sublime Text 3\subl.exe" set git-bash="C:\Program Fi ...

  5. 重写方法的利器-super

    重写方法的利器-super class ilist(list): def __init__(self,dft=None,r=list()): super(ilist, self).__init__(r ...

  6. Linux 高性能服务器编程——TCP协议详解

    问题聚焦:     本节从如下四个方面讨论TCP协议:     TCP头部信息:指定通信的源端端口号.目的端端口号.管理TCP连接,控制两个方向的数据流     TCP状态转移过程:TCP连接的任意一 ...

  7. android SlidingmMenu的入门介绍

    最近了解了SlidingMenu控件的使用,之前手机qq等软件都采用了这种控件,所以还是很有必要学些这个控件的使用方法. 这个控件是基于github的一个开源项目. 地址是: https://gith ...

  8. 在自己笔记本电脑上如何访问虚拟机的内容、包括可以使用ssh、访问tomcat、访问nginx

    1.给自己的电脑设置一个回环网卡,关于如何配置回环网卡,可以百度搜索一下 设置好后的状态如下: 并把回环网卡的ipv4的值设置成192.168.1.1 配置如下: 2.将vmware中的"虚 ...

  9. Struts 2 之配置文件

    Struts 1使用ActionServlet作为分发器,而Struts 2使用Filter作为分发器.如果有多个Filter,要把Struts 2的分发器Filter放在最后 web.xml < ...

  10. 嵌入式LINUX环境下视频采集知识

    V4L2是Linux环境下开发视频采集设备驱动程序的一套规范(API),它为驱动程序的编写提供统一的接口,并将所有的视频采集设备的驱动程序都纳入其的管理之中.V4L2不仅给驱动程序编写者带来极大的方便 ...