為移動端網頁構造快速響應按鈕

背景

在谷歌,我們不斷地推測手機網頁應用的可能性。像HTML5這樣的技術使我們網頁版的應用以及運行在手機設備上的原生應用。而這些技術的成就之一就是我們開發了一種新的創建按鈕的方法,使按鈕的響應時間遠遠快于一般的HTML按鈕。在此之前的按鈕或者其他響應事件,我們可能會設計一個點擊事件。例如:

<button οnclick='signUp()'>Sign Up!</button>
這種方法的問題是,當你開始點擊按鈕開啟點擊事件時,瀏覽器會停留大約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

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/377182.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/377182.shtml
英文地址,請注明出處:http://en.pswp.cn/news/377182.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Red Gate系列之一 SQL Compare 10.4.8.87 Edition 數據庫比較工具 完全破解+使用教程

Red Gate系列之一 SQL Compare 10.4.8.87 Edition 數據庫比較工具 完全破解使用教程 Red Gate系列文章&#xff1a; Red Gate系列之一 SQL Compare 10.4.8.87 Edition 數據庫比較工具 完全破解使用教程 Red Gate系列之二 SQL Source Control 3.0.13.4214 Edition 數據庫版本控制…

《MySQL——基于位點orGTID的主備切換協議》

一主多從的設置&#xff0c;用于讀寫分離&#xff0c;主庫負責所有的寫入和一部分讀&#xff0c;其他讀請求則由從庫分擔。 一主多從架構下&#xff0c;主庫故障后的主備切換問題。相比于一主一備&#xff0c;多了從庫指向新主庫的過程。 基于位點的主備切換同步 把節點B設…

數據科學和統計學_數據科學中的統計

數據科學和統計學統計 (Statistics) Statistics are utilized to process complex issues in reality with the goal that Data Scientists and Analysts can search for important patterns and changes in Data. In straightforward words, Statistics can be utilized to ge…

java隨機數生成(固定位數)

隨機生成 a 到 b (不包含b)的整數:(int)(Math.random()*(b-a))a; 隨機生成 a 到 b (包含b)的整數:(int)(Math.random()*(b-a1))a;轉載于:https://www.cnblogs.com/zhwl/p/3624726.html

POJ 3670 Eating Together

POJ_3670 由于遞增和遞減是類似的&#xff0c;下面不妨只討論變成遞增序列的情況。 由于Di只有三個數&#xff0c;所以可以考慮將序列分割成三部分&#xff0c;第一部分全部變成1&#xff0c;第二部分全部變成2&#xff0c;第三部分全部變成3。然后我們枚舉3開始的位置&#xf…

《MySQL——如何解決一主多從的讀寫分離的過期讀問題》

目錄兩種架構兩種架構特點強制走主庫方案Sleep方案判斷主備無延遲方案配合semi-sync等主庫位點方案GTID方案兩種架構 基于一主多從的讀寫分離&#xff0c;如何處理主備延遲導致的讀寫分離問題。 讀寫分離的主要目標&#xff1a;分攤主庫壓力。 有兩種架構&#xff1a; 1、客…

json/ 發送形式_24/7的完整形式是什么?

json/ 發送形式24/7&#xff1a;二十四 (24/7: Twenty-Four Seven) 24/7 or 24-7 service, which generally marked "twenty-four seven" is service that is existing at any time and typically, every day in trade business and industry. Substitute orthograph…

《MySQL tips:并發查詢與并發連接區別》

并發連接與并發查詢&#xff0c;并不是一個概念。 在執行show processlist的結果里&#xff0c;看到了幾千個連接&#xff0c;指的是并發連接。 而"當前正在執行"的語句&#xff0c;才是并發查詢。 并發連接數多影響的是內存。 并發查詢太高對CPU不利。一個機器的…

對上拉下拉電阻的作用作個總結(想了解的過來看看)(轉載)

轉自&#xff1a;http://www.amobbs.com/thread-5475279-1-3.html 一、定義&#xff1a;上拉就是將不確定的信號通過一個電阻嵌位在高電平&#xff01;電阻同時起限流作用&#xff01;下拉同理&#xff01;上拉是對器件注入電流&#xff0c;下拉是輸出電流&#xff1b;弱強只是…

給用戶傳入的變量進行轉義操作

先看代碼實現&#xff1a; /* 對用戶傳入的變量進行轉義操作。*/ if (!get_magic_quotes_gpc()) {if (!empty($_GET)){$_GET addslashes_deep($_GET);}if (!empty($_POST)){$_POST addslashes_deep($_POST);}$_COOKIE addslashes_deep($_COOKIE);$_REQUEST addslashes_…

《MySQL——外部檢測與內部統計 判斷 主庫是否出現問題》

目錄select1判斷查表判斷更新判斷外部檢測弊端內部統計一主一備的雙M架構里&#xff0c;主備切換只需要把客戶端流量切換到備庫。 在一主多從的架構里&#xff0c;主備切換要把客戶端流量切換到備庫&#xff0c;也需要把從庫接到新主庫上。 切換有兩種場景&#xff1a;1、主動…

NIM的完整形式是什么?

NIM&#xff1a;無內部消息 (NIM: No Internal Message) NIM is an abbreviation of "No Internal Message". NIM是“無內部消息”的縮寫。 It is an expression, which is commonly used in the Gmail platform. It is written in the subject of the mail, if the…

[Json] C#ConvertJson|List轉成Json|對象|集合|DataSet|DataTable|DataReader轉成Json (轉載)...

點擊下載 ConvertJson.rar 本類實現了 C#ConvertJson|List轉成Json|對象|集合|DataSet|DataTable|DataReader轉成Json|等功能大家先預覽一下 請看代碼 /// <summary> /// 類說明&#xff1a;Assistant /// 編 碼 人&#xff1a;蘇飛 /// 聯系方式&#xff1a;361983679 …

let 只能在嚴格模式下嗎_LET的完整形式是什么?

let 只能在嚴格模式下嗎LET&#xff1a;今天早早離開 (LET: Leaving Early Today) LET is an abbreviation of "Leaving Early Today". LET是“ Leaveing Today Today”的縮寫 。 It is an expression, which is commonly used in the Gmail platform. It is writt…

js 遮罩層 loading 效果

//調用方法 //關閉事件<button οnclickLayerHide()>關閉</button>&#xff0c;在loadDiv(text)中&#xff0c;剔除出來 //調用LayerShow(text)&#xff0c;text為參數&#xff0c;可以寫入想要寫入的提示語 //本方法在調用時會自動生成一個添加到body的div&#x…

centos6.5安裝配置LDAP服務[轉]

centos6.5安裝配置LDAP服務[轉] 安裝之前查一下 1find / -name openldap*centos6.4默認安裝了LDAP&#xff0c;但沒有裝ldap-server和ldap-client 于是yum安裝 1su root2yum install -y openldap openldap-servers openldap-clients不建議編譯源碼包&#xff0c;有依賴比較麻煩…

《MySQL——恢復數據-誤刪行、表、庫》

目錄誤刪行事前預防誤刪行數據方法誤刪表/庫延遲復制備庫事前預防誤刪庫/表方法傳統的架構不能預防誤刪數據&#xff0c;因為主庫的一個drop table命令&#xff0c;會通過binlog傳給所有從庫和級聯從庫&#xff0c;進而導致整個集群的實例都會執行這個命令。 MySQL相關的誤刪除…

python圖例位置_Python | 圖例位置

python圖例位置Legends are one of the key components of data visualization and plotting. Matplotlib can automatically define a position for a legend in addition to this, it allows us to locate it in our required positions. Following is the list of locations…

Freemarker中遍歷List實例

Freemarker中如何遍歷List摘要&#xff1a;在Freemarker應用中經常會遍歷List獲取需要的數據&#xff0c;并對需要的數據進行排序加工后呈現給用戶。那么在Freemarker中如何遍歷List&#xff0c;并對List中數據進行適當的排序呢&#xff1f;通過下文的介紹&#xff0c;相信您一…

工作總結:文件對話框的分類(C++)

原文地址&#xff1a;http://www.jizhuomi.com/software/173.html 文件對話框分為打開文件對話框和保存文件對話框&#xff0c;相信大家在Windows系統中經常見到這兩種文件對話框。例如&#xff0c;很多編輯軟件像記事本等都有“打開”選項&#xff0c;選擇“打開”后會彈出一個…