英文原文出自 Google Deveploers《Creating Fast Buttons for Mobile Web Applications》,由XiaoYi_HD翻译,并首发于 EsoftMobile.com。如需转载,请注明译者及出处信息。

背景

在 Google,我们不断地突破移动 Web 应用能够达到的效果,类似于 HTML5 这类技术让我们对原生应用和 Web 应用的界线开始变得模糊。为了这个目标,我们开发了一种新技术让纯 HTML 按钮能够有更快的响应速度。这之前,我们可能只是为按钮或者其他可以点击的元素增加点击处理,如:

<button onclick='signUp()'>Sign Up!</button>

使用这种方法存在一个问题就是,移动浏览器会在你点击按钮后 300ms 才触发事件,原因是浏览器需要区分你是否是要执行双击。但是对于大多数按钮,我们并不需要它处理双击事件,所以 300ms 的延时时间对于只是想执行点击事件的用户来说太长了。我们最早开发这种技术是在Google Voice mobile web app中,我们希望能够更加迅速的调用拨号事件。

处理触摸事件

该技术涉及一点 JavaScript 的东西来让按钮响应触摸(Touch)事件而不是点击(Click)事件。触摸事件响应不会有延时所以感受会比点击事件快很多,但是我们也需要考虑以下几个问题:

  1. 如果用户是点击屏幕上其他的元素而触发了按钮的触摸事件,这种情况我们不应该去执行按钮的事件。
  2. 如果用户按下按钮然后拖到屏幕其他位置而触发了触摸事件,我们也不应该执行按钮的事件。
  3. 我们希望按钮在按下的时间能够高亮来表示点击状态。

我们能够通过检测 touchstart 和 touchmove 事件来解决前两个问题,只需要考虑一个一开始在按钮上就是 touchstart 状态的触摸事件,而如果 touchstart 后存在了一个 touchmove,那我们就不应该处理 touchend 事件。

我们可以通过同时给按钮添加 onclick 处理来解决第三个问题,这样浏览器就会把它当成按钮并在点击时出现高亮。我们 touchend 处理也能保证按钮仍然很快响应,同时添加 onclick 可以在不支持触摸事件的浏览器上做为比较可靠的备用方案。

破坏讨厌的点击

在添加触摸事件的同时添加 onclick 事件又会带来另一个讨厌的问题,当你点击按钮时,点击 (click) 事件仍然会在 300ms 后执行,我们可以通过在 touchstart 事件里调用 preventDefault 来解决。在 touchstart 中调用 preventDefault 方法会会导致点击和滑动失效,但我们又想用户能够滑动视图即使一开始是点在按钮上,所以我们仍不能接受这种解决方案。接来下我们想出了一个被我们叫做点击破坏者(Click buster)的方案,我们给 body 添加一个点击事件监听(listener),当监听事件被触发,我们会区分点击是否由我们已经处理的 tap 事件导致的,如果这样,我们才调用 preventDefault 和 stopPropagation。

Fast Button Code

下面我们会提供一些我们实现这个想法的代码。

通过标签和事件创建一个 FastButton

google.ui.FastButton = function(element, handler) {this.element = element;this.handler = handler;element.addEventListener('touchstart', this, false);element.addEventListener('click', this, false);
};google.ui.FastButton.prototype.handleEvent = function(event) {switch(event.type) {case 'touchstart': this.onTouchStart(event); break;case 'touchmove': this.onTouchMove(event); break;case 'touchend': this.onTouchEnd(event); break;case 'click': this.onClick(event); break;}
};

保存 touchstart 坐标,并开始监听 touchmove 和 touchend 事件,调用 stopPropagation 来保证其他操作不会触发点击事件。

google.ui.FastButton.prototype.onTouchStart = function(event) {event.stopPropagation();this.element.addEventListener('touchend', this, false);document.body.element.addEventListener('touchmove', this, false);this.startX = event.touches[0].clientX;this.startY = event.touches[0].clientY;
};

当 touchmove 事件触发时,检查用户是否拖动超过 10px。

google.ui.FastButton.prototype.onTouchMove = function(event) {if (Math.abs(event.touches[0].clientX - this.startX) > 10 ||Math.abs(event.touches[0].clientY - this.startY) > 10) {this.reset();   }
};

执行真正的点击事件并在 touchend 事件时避免讨厌的 click。

google.ui.FastButton.prototype.onClick = function(event) {event.stopPropagation();this.reset();this.handler(event);if (event.type == 'touchend') {google.clickbuster.preventGhostClick(this.startX, this.startY);}
};google.ui.FastButton.prototype.reset = function() {this.element.removeEventListener('touchend', this, false);document.body.removeEventListener('touchmove', this, false);
}

调用 preventGhostClick 来破坏在接下来 2.5s 内 x, 移动距离在 25px 内的点击事件。

google.clickbuster.preventGhostClick = function(x, y) {google.clickbuster.coordinates.push(x ,y);window.setTimeout(google.clickbuster.pop, 2500);
};google.clickbuster.pop = function() {google.clickbuster.coordinates.splice(0, 2);
};

如果我们在给定的半径和时间内捕获到了点击事件,调用 stopPropagation 和 preventDefault。

google.clickbuster.onClick = function(event) {for (var i = 0; i < google.clickbuster.coordinates.length; i += 2) {var x = google.clickbuster.coordinates[i];var y = google.clickbuster.coordinates[i + 1];if (Math.abs(event.clientX - x) < 25 && Math.abs(event.clientY - y) < 25) {event.stopPropagation();event.preventDefault();}}
};document.addEventListener('click', google.clickbuster.onClick, true);
google.clickbuster.coordinates = [];

总结

到这里你应该能够创建快速响应的按钮了,花一点心思,你可以让它们看起来更像你所面向平台的原生按钮。现在已经有一些 JavaScript 库也提供了这种问题的解决方案,但是到目前为止我们没有发现有提供可靠备选方案和讨厌的点击问题。我们希望浏览器开发者能够在能够解决在不能缩放的页面上快速响应的问题,事实上我们已经在 Gingerbread 的浏览器上实现了。

测试代码FastButtonDemo已上传 github。

Posted by XiaoYi_HD - 6月 27 2013
如需转载,请注明: 本文来自 Esoft Mobile

转载于:https://www.cnblogs.com/tracy-e/p/3161847.html

为移动Web应用创建快速响应按钮相关推荐

  1. 为移动端网页构造快速响应按钮

    背景 在谷歌,我们不断地推测手机网页应用的可能性.像HTML5这样的技术使我们网页版的应用以及运行在手机设备上的原生应用.而这些技术的成就之一就是我们开发了一种新的创建按钮的方法,使按钮的响应时间远远 ...

  2. 最详细的 SAP ABAP Web Service 创建和消费步骤讲解

    本文原版发表于 SAP 官方社区,当时用的英文版写作,标题为:Step by step to create, consume and trace web service in ABAP system ...

  3. MyEclipse教程:Web开发——创建Web片段项目

    MyEclipse 在线订购年终抄底促销!火爆开抢>> MyEclipse最新版下载 本教程向用户展示了使用关联的Web项目创建Web片段项目的机制. 用户还可以获得要检查的示例项目. 在 ...

  4. Unity 3D 2019.3.12版本创建一个按钮,并为该按钮添加点击Click的消息响应函数以及点击按钮切换场景

    1. 创建一个GameObject对象 菜单[GameObject]选择[Create Empty],此时可在[Hierarchy]窗口看到生成的GameObject对象,并且[Inspector]窗 ...

  5. Qt中多个动态创建的按钮同时绑定一个槽函数,判断被点击的是哪个按钮

    当动态创建按钮,每一个创建的按钮都与同一个槽函数绑定,点击按钮的时候获取被点击的按钮的文本. 代码如下: QString getClickedBtn() {outPut<<"ge ...

  6. android升序降序按钮,创建一个按钮,将排序MYSQL查询升序和降序

    我是一名学生编码器. 我想创建一个排序按钮,当按下时,按升序排序MYSQL查询.然后再次按下时,它将按降序排列.对,现在,它只是显示升序和降序表背靠背.创建一个按钮,将排序MYSQL查询升序和降序 形 ...

  7. gradle——eclipse中安装与web项目创建

    一.引言 创世之初,世上只有Make一种构建工具,后来,其发展为GNU Make.但是,由于需求的不断涌现,码农的世界里逐渐演化出了千奇百怪的构建工具. 当前,JVM生态圈由三大构建工具所统治: Ap ...

  8. 用HTML5 Canvas为Web图形创建特效

    HTML5 Canvas 将使用像素在屏幕上绘制图形图像. 本节演示了五种用于操作像素以创建摄影特效的 Canvas 技术. 您可使用这些技术来生成独具特色的图像,为您的网站.博客.视频游戏画面.广告 ...

  9. excel网页服务器端,Excel服务VI――用Excel Web Services创建应用程

    译者:fanjy  来源:http://blogs.msdn.com/excel 发表于:2006年7月7日 Excel Services part 6: Building applications ...

  10. iOS创建浮动按钮,点击按钮“置顶”

    1.创建浮动按钮 -(void)CreateFloadWindow {// *****创建浮动按钮的关键语句,设置按钮的Frame值****CGRect floatFrame = CGRectMake ...

最新文章

  1. java_泛型 TreeSet 判断hashcode/length(升序排列)
  2. 把学生类按单科成绩排序_重庆新高考几个核心点:分数线种类、96个志愿、投档排序规则...
  3. 12025.petalinux 之phy调试ping(三)
  4. C++组合数(combination)的实现
  5. 选择物联网卡平台时需要重点考虑的标准
  6. java程序本质,方法学之Java的本质
  7. 让IIS只监听一个IP上的80端口
  8. 数字电路基础知识——锁存器与触发器在Verilog中使用问题
  9. 数据库建模-概念模型建模(E-R图)
  10. 银河麒麟V10(Kylin Linux V10)安装 Kibana-7.15.2
  11. 安装/卸载office2003出现“无法打开此修补程序包”错误
  12. Python相对导入:ValueError: attempted relative import beyond top-level package
  13. 给Docker NodeRed 设置登陆账户
  14. apache服务器安装以及使用passenger插件部署rails应用,基于ubuntu 12.04 LTS
  15. 数据库原理及应用(MySQL版)MySQL实验指导参考答案(实验一到实验八)
  16. JS元素的提取,删除 ,添加,修改
  17. 辩论赛计算机软件更重要论据,善意的谎言辩论会正方观点要例子
  18. 给定一个大小为 *n* 的数组,找到其中的多数元素。多数元素是指在数组中出现次数大于 *⌊ n/2 ⌋* 的元素。
  19. 【原创】JavaWeb仓库管理系统(Web仓库管理系统毕业设计)
  20. Echarts配置项-2

热门文章

  1. SecureCRT for Mac(强大的终端SSH工具)
  2. 如何为Mac视频添加模糊效果?
  3. Linux中关于httpd仓库安装的简要步骤
  4. BeyondCompare This license key has been revoked:
  5. Makefile中变量赋值方式
  6. 提取HTML代码中的网址
  7. 编写 if 时尽量不要带 else
  8. 全网最全的IDEA热部署方案,看完弄懂,再也不用加班了~
  9. 悲剧!因Redis分布式锁造成的P0级重大事故,整个项目组被扣了绩效...
  10. Spring 面试 7 大问题,你顶得住不?