原文: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. windows10,redhat6.5下python3.5.2使用cx_Oracle链接oracle

    0.序言 项目主要使用oracle但是我不太喜欢其他编程语言,加上可能需要用python部署算法包,从oracle表中读出数据,处理完成后在放回oracle中去,所以在windows上就想到先用pyt ...

  2. linux TCP头部的构造的简单分析

    TCP的头部的构造是在函数tcp_transmit_skb()中进行的 函数片段如下: /* Build TCP header and checksum it. */ th = tcp_hdr(skb ...

  3. 独立开发一个云(PaaS)的核心要素, Go, Go, Go!!!

    最近一年的工作,有很大的比重在做云平台的事情,简单来说,就是为公司内用户提供一个PaaS,用户可以在我们的云平台上方便的将单机服务程序扩展为多实例程序,以平台服务化的方式对外提供.在这里简单分享一下. ...

  4. 我的第一本著作:Spark技术内幕上市!

    现在各大网站销售中! 京东:http://item.jd.com/11770787.html 当当:http://product.dangdang.com/23776595.html 亚马逊:http ...

  5. uboot-tiny4412启动流程(下)----如何将自己的裸板测试程序加入uboot中启动测试

    今天在工作上搞了一天高通的芯片uboot程序,目的是希望将一个裸板的程序移植到uboot中,并且开机让它运行.这个芯片是NXP4330,目前是高通的一个芯片,基于ARM-contexA9架构,那么就跟 ...

  6. Linux Java开发坏境搭建,Ubuntu-jdk+tomcat+eclipse+svn 包安装详细操作

    更新时间2015-03-15 更新2015-04-12 svn安装更新 第一步 安装jdk (在linux上使用yum安装JDK  http://blog.chinaunix.net/uid-1546 ...

  7. Android传感器

    Android传感器 开发传感器应用 1. 获取传感器管理者对象 // 获取传感器管理者对象 SensorManager mSensorManager = (SensorManager) getSys ...

  8. JQuery之DOM操作及常用函数

    属性操作 attr(name)获取属性值 var imgSrc = $("img").attr("src") attr(name,value)设置属性值 $(& ...

  9. Android开发学习之路--RxAndroid之操作符

      学习了RxAndroid的一些基本知识,上篇文章也试过了RxAndroid的map操作符,接着来学习更多的操作符的功能吧.   操作符就是为了解决对Observable对象的变换的问题,操作符用于 ...

  10. Linux系统编程-----进程fork()

    在开始之前,我们先来了解一些基本的概念: 1. 程序, 没有在运行的可执行文件 进程, 运行中的程序 2. 进程调度的方法: 按时间片轮转 先来先服务 短时间优先 按优先级别 3. 进程的状态: 就绪 ...