为移动端网页构造快速响应按钮
背景在谷歌,我们不断地推测手机网页应用的可能性。像HTML5这样的技术使我们网页版的应用以及运行在手机设备上的原生应用。而这些技术的成就之一就是我们开发了一种新的创建按钮的方法,使按钮的响应时间远远快于一般的HTML按钮。在此之前的按钮或者其他响应事件,我们可能会设计一个点击事件。例如:
这种方法的问题是,当你开始点击按钮开启点击事件时,浏览器会停留大约300毫秒的时间。这是因为浏览器在等待,看你是否双击按钮。对于大多数的按钮,我们在开发的时候就知道不会执行双击事件,所以点击后等待的这段时间是在浪费用户的时间。我们在Google Voice手机网页应用上第一次使用这种技术,目的是想让用户拨号时有更快的相应速度。 |
处理触摸事件这个技术涉及到一点javascript,允许按钮对touchEnd事件响应而不是click事件。touchEnd事件的触发是没有延迟的,所以能够明显的比click事件要快,但是仍有一些问题值得考虑: 1.如果用户轻触了屏幕的某个地方然后引起了一个按钮的touchEnd事件,而我们不应该由此触发一个click事件。 2.如果用户按下了按钮,然后在屏幕上拖动了一段距离,然后引起按钮的touchEnd事件,此时我们也不应该触发click事件。 3.我们希望当用户按下按钮时,能够给这个按钮一个按下的状态,从而使得其突出显示。 |
我们能够通过监听touchStart和touchMove事件解决前两个问题。如果在按钮上之前有touchStart事件,那么我们才会考虑在按钮上的touchEnd事件。同样,如果有一个touchMove事件且同touchStart的位置相比移动超过了某个阈值,那么我们就不应该把这个touchEnd事件当做click事件来处理。 我们也可以通过给按钮添加一个onclick处理函数来解决第三个问题。那么做会恰好让浏览器于把他当做按钮,而我们的touchEnd处理函数仍能够确保这个按钮响应很快。同样,一个onclick处理函数的存在,也能让那些不支持touch事件的浏览器优雅降级。 |
消除幽灵点击重新添加onclick处理函数给按钮,会引发最后一个令人讨厌的问题。但你轻触按钮时,一个click事件仍然会在300ms后被触发。现在这个click处理函数就有被运行两次的危险。这个可以通过在touchStart事件中调用preventDefault 很容易被解决。在touchStart事件中调用preventDefault方法将会阻止当前的轻触所引发的的click和scrolling。我们希望用户可以滚动页面,即使他们从按钮的位置开始滚动,所以我们不认为这是一个可接受的解决方案。我们想出的能解决幽灵点击的方法叫做click buster(点击破坏者)。我们所做的只是在页面body中添加一个click的监听器,在捕获阶段监听。当我们的监听器被触发,我们就会尝试判定这个click事件是不是我们已经当做tap事件来处理的结果。如果是的话,我们就可以调用preventDefault和stopPropagation来阻止他。 |
(function(){/** * From: http://code.this.com/mobile/articles/fast_buttons.html* Also see: http://stackoverflow.com/questions/6300136/trying-to-implement-googles-fast-button*//** For IE8 and earlier compatibility: https://developer.mozilla.org/en/DOM/element.addEventListener */function addListener(el, type, listener, useCapture){if (el.addEventListener) {el.addEventListener(type, listener, useCapture);return {destroy: function(){el.removeEventListener(type, listener, useCapture);}};}else {var handler = function(e){listener.handleEvent(window.event, listener);}el.attachEvent('on' + type, handler);return {destroy: function(){el.detachEvent('on' + type, handler);}};}}var isTouch = "ontouchstart" in window;/* 构建fastbutton与元素的引用并单击处理程序. */this.FastButton = function(element, handler, useCapture){// 收集功能调用清除事件 this.events = [];this.touchEvents = [];this.element = element;this.handler = handler;this.useCapture = useCapture;if (isTouch) this.events.push(addListener(element, 'touchstart', this, this.useCapture));this.events.push(addListener(element, 'click', this, this.useCapture));};/* 移除事件处理时,不再需要这个按钮 */this.FastButton.prototype.destroy = function(){for (i = this.events.length - 1; i >= 0; i -= 1) this.events[i].destroy();this.events = this.touchEvents = this.element = this.handler = this.fastButton = null;};/* 作为一个事件调度 */this.FastButton.prototype.handleEvent = function(event){switch (event.type) {case 'touchstart':this.onTouchStart(event);break;case 'touchmove':this.onTouchMove(event);break;case 'touchend':this.onClick(event);break;case 'click':this.onClick(event);break;}};/* 保留对touchStart位置的引用,然后开始监听touchMove和touchEnd事件。调用stopPropagation来保证另一个动作不会再次处理同样的点击事件. */this.FastButton.prototype.onTouchStart = function(event){event.stopPropagation ? event.stopPropagation() : (event.cancelBubble = true);this.touchEvents.push(addListener(this.element, 'touchend', this, this.useCapture));this.touchEvents.push(addListener(document.body, 'touchmove', this, this.useCapture));this.startX = event.touches[0].clientX;this.startY = event.touches[0].clientY;};/* 当一个touchMove事件被触发,检查用户是否推动超过10px这个阈值. */this.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(); //如果ture,然后取消触摸事件 }};/*触发一个实际的click处理函数,如果有touchEnd事件,就阻止幽灵点击事件. */this.FastButton.prototype.onClick = function(event){event.stopPropagation ? event.stopPropagation() : (event.cancelBubble = true);this.reset();// Use .call to call the method so that we have the correct "this": https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/callvar result = this.handler.call(this.element, event);if (event.type == 'touchend') clickbuster.preventGhostClick(this.startX, this.startY);return result;};this.FastButton.prototype.reset = function(){for (i = this.touchEvents.length - 1; i >= 0; i -= 1) this.touchEvents[i].destroy();this.touchEvents = [];};this.clickbuster = function(){}/* 调用preventGhostClick来消除掉所有的在2.5s内且在不超过保留的x,y坐标周围25px的点击事件 */this.clickbuster.preventGhostClick = function(x, y){clickbuster.coordinates.push(x, y);window.setTimeout(clickbuster.pop, 2500);};this.clickbuster.pop = function(){clickbuster.coordinates.splice(0, 2);};/*如果我们 在给定的范围和时间阈值里捕捉到一个click事件,我们调用stopPropagation和preventDefault。调用preventDefault能够阻止链接变为activated状态。 */this.clickbuster.onClick = function(event){for (var i = 0; i < clickbuster.coordinates.length; i += 2) {var x = clickbuster.coordinates[i];var y = clickbuster.coordinates[i + 1];if (Math.abs(event.clientX - x) < 25 && Math.abs(event.clientY - y) < 25) {event.stopPropagation ? event.stopPropagation() : (event.cancelBubble = true);event.preventDefault ? event.preventDefault() : (event.returnValue = false);}}};if (isTouch) {// 不需要使用我们的自定义功能,因为我们只需要触摸设备上点击document.addEventListener('click', clickbuster.onClick, true);clickbuster.coordinates = [];}})(this);window.onload = function(){new FastButton(document.getElementById('id2'), function(){alert('click');});}
View Code
总结基于这一点,你应该很容易就可以创建快速响应的按钮。通过一些奇特的方式,你能够使这些按钮看起来像是基于你的开发平台的本地按钮一样。已经有一些解决同样问题的移动javascript库可以使用了,但是我们还从未见过任何一个能够提供click事件的优雅降级或者幽灵点击事件的解决方案的js库。我们希望浏览器的开发者们能够在将来的版本中,通过当网站的缩放被禁止(通过使用viewport的meta标签)时,能直接触发click事件的方式解决这个问题。实际上,这已经是姜饼版安卓浏览器要解决的事情了。 |
英文原文:Creating Fast Buttons for Mobile Web Applications
转载于:https://www.cnblogs.com/niubenbit/p/3623550.html
为移动端网页构造快速响应按钮相关推荐
- uni-app - 最详细 H5 网页接入微信登录功能,提供公众号配置与详细注释示例代码(移动端网页实现点击登录按钮后 调用微信公众号授权登录功能 详细讲解接入流程与详细示例代码)官方最新超级详细教程
前言 关于 uni-app 项目中接入微信授权登录的文章鱼龙混杂,各种乱代码.过时.没注释.不讲流程原理,非常难用. 本文实现了 uni-app H5 移动端网页项目,实现微信授权登录功能,详细讲解接 ...
- 网络爬虫中Fiddler抓取PC端网页数据包与手机端APP数据包
1 引言 在编写网络爬虫时,第一步(也是极为关键一步)就是对网络的请求(request)和回复(response)进行分析,寻找其中的规律,然后才能通过网络爬虫进行模拟.浏览器大多也自带有调试工具可以 ...
- javaScript PC端网页特效
PC端网页特效 1. 元素偏移量 offset 系列 1.1 offset 概述 1.2 offset 与 style 区别 2. 元素可视区 client 系列 2.1 立即执行函数 2.2 loa ...
- 推荐3款移动端网页开发调试神器
web前端教程 用大白话,来讲编程 最近有小伙伴在微信上跟我聊到了移动端网页开发调试困哪的问题,这个相信很多前端开发者都遇到过. 有一天,测试妹子拿着测试手机过来找你,说页面打不开. 你心想:怎么可能 ...
- 【移动端网页布局】移动端网页布局基础概念 ① ( 移动端浏览器 | 移动端屏幕分辨率 | 移动端网页调试方法 )
文章目录 一.移动端浏览器 二.移动端屏幕分辨率 三.移动端网页调试方法 一.移动端浏览器 移动端浏览器 比 PC 端浏览器发展要晚 , 使用的技术比较新 , 对 HTML5 + CSS3 支持较好 ...
- 小程序嵌入web-view网页后,点击网页中的按钮跳转回小程序
1.首先在网页端引入js <script type="text/javascript" src="https://res.wx.qq.com/open/js/jwe ...
- PC端和移动端网页特效,fastclick插件,Swiper插件,Bootstrap等框架,本地存储
目录 PC 端网页特效 元素偏移量 offset 系列 1.offset 系列常用属性 2.offset 与 style 区别 3.计算鼠标在盒子内的坐标 4.模态框拖拽 5.京东商品放大镜 元素可视 ...
- web端 网页端分享功能的实现
思路 web端 网页端分享功能的实现. 我们看微信的分享开发者文档,可以知道使用微信JS-SDK可以实现网页在微信里的分享. 微信JS-SDK说明文档 也就是说 在微信浏览器中打开的网页 才能调用 该 ...
- html5多屏互动游戏,多屏互动 —— 手机端与PC端 网页互动的现有尝试及设想
不可否认,多屏时代已经到来. 手机/平板/笔记本/PC/TV等,多个显示平台的逐步构建,为信息传播及交互提供了多重平台及体验选择. 素材:多屏自适应网页设计/多屏延生设计 在此篇文章,取手机端与PC端 ...
最新文章
- java MD5 并发
- leetcode580. 统计各专业学生人数(SQL)
- numpy python 兼容_Python 2和3之间的numpy数组的不兼容性
- NPOI操作word文档
- freertos 创建互斥量_FreeRTOS的信号量和互斥量
- 海量存储——致性和高可用专题
- 湖南城市学院计算机题库和答案,湖南城市学院 计算机选择题题库
- HDU-5781 ATM Mechine(概率DP)
- VB.NET连接SQL数据库
- Linux 添加中文字体库
- 为知笔记linux输入中文,为知笔记wiznote无法输入中文,fcitx输入法问题解决
- 在python中for i in range是什么意思-Python for i in range ()用法详解
- 仓库管理一团糟,WMS仓库管理系统如何解决这些难点
- 腾讯云认证证书——云计算行业的敲门砖
- NetBeans IDE使用方法
- R语言入门(2)时间序列分析原理
- 视频前景提取 (III)【Mat版本】
- 微型计算机的型号是奔四800,第1章 微型计算机基础知识
- 使用DOS重定位技术执行isqlw(SQL查询分析器)
- simhash算法原理
热门文章
- 闰秒对数据库和linux的影响
- 《linux 网卡别名的添加和绑定》RHEL6
- Android 4.0 Launcher源码分析系列(二)
- 职场交流:一位软件工程师的7年总结
- 深圳敏捷云计算机科技,敏捷云 | 关于我们 | 敏捷云
- Pytorch GRU(详解GRU+torch.nn.GRU()实现)
- 按键精灵调用迅雷下载文件
- 计算机程序备份,将应用程序快照备份到计算机
- excel实战应用案例100讲(十二)-用Excel做一个自动抽奖器
- Linux程序选择boy糊者girl,linux脚本程序练习-Go语言中文社区