资讯专栏INFORMATION COLUMN

Browser Input Events:Can We Do Better Than The Cli

felix0913 / 3372人阅读

摘要:指针事件给用户代理带来灵活性,给一个事件系统提供丰富的输入机制。就像苹果和谷歌现在就没有打算来实现指针事件。谷歌的这个决定并不是他们最终的决定,但是目前在指针事件上没有活跃的工作。

  

原文地址:http://tw93.github.io/2015-03-30/Browser-input-Events.html

响应用户的输入可以说是我们做界面开发的核心。为了构建可响应的Web产品,理解触摸、鼠标、指针、键盘操作和浏览器的工作原理是解决问题的关键。你可能在手机浏览器中经历过300-millisecond delay(300 ms延迟)或者wrestled with touchmove versus scrolling(触摸滚动导致页面卡顿)。

在本文中,我们将介绍事件级联和使用这些知识来实现演示一个tap点击事件,支持多种输入方法但是又没有违反像Opera Mini这一类的代理浏览器规则。

注:tap也翻译为点击,tap和click都是在点击时候触发,但在手机Web端click会有200~300ms延迟,为了避免歧义,下文将” tap event“翻译成“tap点击事件“

概况

目前被用于与Web交互的3种主要的交互方式是:数字光标(鼠标)、触觉(直接触摸或者手写笔)、键盘。在JavaScript中我们可以通过触摸事件,鼠标事件,指针事件和键盘事件来使用它们。在这篇文章中我们主要讨论触摸和基于鼠标的交互,虽然这里有键盘事件已经形成标准,如click和submit事件。

你很有可能已经实现过鼠标和触摸事件的处理程序,在过去我们推荐的做法是这样:

javascript/** DO NOT EVER DO THIS! */
$("a", ("ontouchstart" in window)?"touchend":"click",handler);

微软已经负责创建了一个更好的,更有前途的“指针事件”的事件模型规范。指针事件是一个抽象的输入机制,现在是W3C推荐标准。指针事件给用户代理(UA)带来灵活性,给一个事件系统提供丰富的输入机制。鼠标、触摸、手写笔是今天很容易想到的输入方式,但实现延伸到myo(肌)和Ring(环)也是可实现的。虽然Web开发者对这些似乎很兴奋,但并不是所有的浏览器开发者也会这样以为。就像苹果和谷歌现在就没有打算来实现指针事件。

谷歌的这个决定并不是他们最终的决定,但是目前在指针事件上没有活跃的工作。我们通过polyfills输入和使用指针事件和替代解决方案将成为等式的一部分,可能最终起决定作用。苹果在2012年发表申明反对指针事件,我现在没有从Safari的工程师那里得到任何公众回应。

事件级联

当用户在移动设备上面tap点击一个元素时,浏览器会触发一系列事件:

  

touchstart → touchend → mouseover → mousemove → mousedown → mouseup → click

这是由于Web的向后兼容性,指针事件采取的一种可替代方案来触发事件内联的兼容性:

  

mousemove → pointerover → mouseover → pointerdown → mousedown → gotpointercapture → pointerup → mouseup → lostpointercapture → pointerout → mouseout → focus → click

事件规范允许用户代理们用不同的方式来实现兼容性的事件,Patrick Lauke和Peter-Paul Koch维护着关于这一主题的广泛的参考材料(资源链接位于文章底部)。
以下图片显示下列行为的事件串:

首次tap点击一个元素

第二次tap点击一个元素

tap点击关闭元素

请注意:为了适应这个栈这个事件栈故意忽略了focus和blur事件。

在IOS设备上的tap点击一个元素两次和松开的事件级联

在 Android 4.4 设备上的tap点击一个元素两次和松开的事件级联

在Internet Explorer 11(在兼容的触摸事件实现)上tap点击元素两次然后松开的事件级联

应用事件级联

由于浏览器工程师的工作,大多数现在建成的桌面网站“只是可以工作而已”。尽管级联看起来有点粗糙,但建立鼠标事件是我们以前通常工作的保守做法。

当然,300ms的延迟问题比起在滚动和touchmove和pointermove事件相互作用,还有浏览器渲染问题这些额外的问题更加臭名昭著。避免300 ms的延迟很容易,如果:

我们只为现代的Android和桌面端的Chrome优化,通过使用来启动禁用延迟这一功能。

我们只为IOS设备优化,用户有一个明确的点击,不是那种快速的点击或者长按,仅仅是一个元素良好的、正常的、明确的点击。

如果我们的目标是建立一个能在用户体验和本地应用媲美的Web应用,那么我们需要减少交互响应的延迟。为了达到这个目标,我们需要在原始事件(如down,move,up)上创建我们属于自己的复合事件(click,double-click),当然我们还需要对本地事件的回退处理提供广泛和可行的支持。

做这些需要不少的代码和知识。为了避免在浏览器中的300ms延迟,我们需要处理全部生命周期内的自我交互。对于一个给定{类型}的down事件,我们需要绑定所有必需的事件来完成这个功能,当交互已经完成后,我们需要清理自己解绑的起始事件。

网站开发人员,你是唯一一个知道页面是否应该放大或另一个双击事件是否必须等待的人。如果只有你需要回调推迟你应该允许一个预定的动作来延迟。

在接下来链接中,你会发现一个小的、相互间无依赖的tap事件Demo来创造一个多输入、低延迟的tap点击事件。Polymer-gestures是一个为tap点击和其他事件生产开发的库。尽管是这个名字有Polymer,但是它是不依赖Polymer库而且很容易被隔离。

明确的说,实施这个从一开始来说就是一个坏主意,以下这些应该仅仅用于教育而不是用于生产环境。用于生产环境的库已经存在,例如: FastClick,polymer-gestures和Hammer.js。

Demo:The tap event

Code:taps.js

重要部分

在所有开始的地方绑定你的初始事件,这下面处理多输入的模式是被认为一种保险的方式。

javascript/**
 * If there are pointer events, let the platform handle the input 
 * mechanism abstraction. If not, then it’s on you to handle 
 * between mouse and touch events.
 */

if (hasPointer) {
  tappable.addEventListener(POINTER_DOWN, tapStart, false);
  clickable.addEventListener(POINTER_DOWN, clickStart, false);
}

else {
  tappable.addEventListener("mousedown", tapStart, false);
  clickable.addEventListener("mousedown", clickStart, false);

  if (hasTouch) {
    tappable.addEventListener("touchstart", tapStart, false);
    clickable.addEventListener("touchstart", clickStart, false);
  }
}

clickable.addEventListener("click", clickEnd, false);

绑定touch事件需要和渲染性能妥协,即使它们没有做任何事,但为了减少这种影响,通常推荐在处理程序开始时候绑定跟踪事件。别忘了在完成你的事件处理后要清理自己的环境和解绑跟踪事件。

javascript/**
 * On tapStart we want to bind our move and end events to detect 
 * whether this is a “tap” action.
 * @param {Event} event the browser event object
 */

function tapStart(event) {
  // bind tracking events. “bindEventsFor” is a helper that automatically 
  // binds the appropriate pointer, touch or mouse events based on our 
  // current event type. Additionally, it saves the event target to give 
  // us similar behavior to pointer events’ “setPointerCapture” method.

  bindEventsFor(event.type, event.target);
  if (typeof event.setPointerCapture === "function") {
    event.currentTarget.setPointerCapture(event.pointerId);
  }

  // prevent the cascade
  event.preventDefault();

  // start our profiler to track time between events
  set(event, "tapStart", Date.now());
}

/**
 * tapEnd. Our work here is done. Let’s clean up our tracking events.
 * @param {Element} target the html element
 * @param {Event} event the browser event object
 */

function tapEnd(target, event) {
  unbindEventsFor(event.type, target);
  var _id = idFor(event);
  log("Tap", diff(get(_id, "tapStart"), Date.now()));
  setTimeout(function() {
    delete events[_id];
  });

剩下的这些代码应该能够很好的自我解释,事实上,它有很多簿记,实现自定义手势要求你用浏览器事件系统来紧密合作。为了挽救你的受伤和心痛,不要在你自己的代码库里做事情。相反你应该建立或使用一个强大的抽象,例如Hammer.js,jQuery polyfill的Pointer Events或者polymer-gestures。

总结

一些曾经很清楚的事件现在却是有歧义的,以前click事件用来指有且只有一件事,但是现在在触摸屏上面需要辨别是双击、滚动或者其他操作系统的手势。

好消息是,我们现在明白了很多用户的操作习惯和浏览器的响应之间的事件级联和相互作用,通过在工作中认识的原语,我们自己能够在我们的项目中为我们的用户和Web的未来做出更好的决策。

你在构建多设备的网站时,有遇到什么意想不到的问题?你采取什么样的方法来解决Web上众多的交互模式?

额外的资源

“Pointer Events Finalized, But Apple’s Lack of Support Still a Deal Breaker,”Peter Bright

Getting Touchy: An Introduction to Touch and Pointer Events,包括slides和talk Patrick E. Lauke

“Apple’s Web?” by Tim Kadlec

“Avoiding the 300ms Click Delay, Accessibly,” Tim Kadlec

“Touch taple,” Peter-Paul Koch

“Making the Web ‘Just Work’ With Any Input: Mouse, Touch, and Pointer Events,” Jacob Rossi

FastClick library

Hammer.js

polymer-gestures

Pointer EventsjQuery polyfill

“Implement Custom Gestures,” Google Developers

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/85613.html

相关文章

  • web现状谈及前端性能优化

    摘要:从现状谈及性能优化原文出处性能优化指南如今网络发展迅猛,这对我们构建的互联网平台要求也更高。这就说明,我们在开发时,并没有站在用户的角度上换位思考,更别谈性能优化。因此,我们可通过区分关键资源并调整加载的优先级来实现性能优化。 从web现状谈及性能优化 原文出处:《Karolina Szczur: The State of the Web》 性能优化指南The Internet is ...

    paney129 评论0 收藏0
  • web现状谈及前端性能优化

    摘要:从现状谈及性能优化原文出处性能优化指南如今网络发展迅猛,这对我们构建的互联网平台要求也更高。这就说明,我们在开发时,并没有站在用户的角度上换位思考,更别谈性能优化。因此,我们可通过区分关键资源并调整加载的优先级来实现性能优化。 从web现状谈及性能优化 原文出处:《Karolina Szczur: The State of the Web》 性能优化指南The Internet is ...

    young.li 评论0 收藏0
  • web现状谈及前端性能优化

    摘要:从现状谈及性能优化原文出处性能优化指南如今网络发展迅猛,这对我们构建的互联网平台要求也更高。这就说明,我们在开发时,并没有站在用户的角度上换位思考,更别谈性能优化。因此,我们可通过区分关键资源并调整加载的优先级来实现性能优化。 从web现状谈及性能优化 原文出处:《Karolina Szczur: The State of the Web》 性能优化指南The Internet is ...

    mzlogin 评论0 收藏0
  • Learning Notes - Understanding the Weird Parts of

    摘要:标签前端作者更多文章个人网站 Learning Notes - Understanding the Weird Parts of JavaScript 标签 : 前端 JavaScript [TOC] The learning notes of the MOOC JavaScript: Understanding the Weird Parts on Udemy,including...

    inapt 评论0 收藏0
  • Python-Socket-Programming(1)

    摘要: Abstract Sockets are used nearly everywhere, but are one of the most severely misunderstood technologies around. This is a 10,000 foot overview of sockets. It’s not really a tutorial - you’ll s...

    animabear 评论0 收藏0

发表评论

0条评论

felix0913

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<