生活随笔
收集整理的這篇文章主要介紹了
为移动端网页构造快速响应按钮
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
背景 在谷歌,我們不斷地推測手機網(wǎng)頁應(yīng)用的可能性。像HTML5這樣的技術(shù)使我們網(wǎng)頁版的應(yīng)用以及運行在手機設(shè)備上的原生應(yīng)用。而這些技術(shù)的成就之一就是我們開發(fā)了一種新的創(chuàng)建按鈕的方法,使按鈕的響應(yīng)時間遠(yuǎn)遠(yuǎn)快于一般的HTML按鈕。在此之前的按鈕或者其他響應(yīng)事件,我們可能會設(shè)計一個點擊事件。例如: <button οnclick='signUp()'>Sign Up!</button> 這種方法的問題是,當(dāng)你開始點擊按鈕開啟點擊事件時,瀏覽器會停留大約300毫秒的時間。這是因為瀏覽器在等待,看你是否雙擊按鈕。對于大多數(shù)的按鈕,我們在開發(fā)的時候就知道不會執(zhí)行雙擊事件,所以點擊后等待的這段時間是在浪費用戶的時間。我們在Google Voice手機網(wǎng)頁應(yīng)用上第一次使用這種技術(shù),目的是想讓用戶撥號時有更快的相應(yīng)速度。 |
處理觸摸事件 這個技術(shù)涉及到一點javascript,允許按鈕對touchEnd事件響應(yīng)而不是click事件。touchEnd事件的觸發(fā)是沒有延遲的,所以能夠明顯的比click事件要快,但是仍有一些問題值得考慮: 1.如果用戶輕觸了屏幕的某個地方然后引起了一個按鈕的touchEnd事件,而我們不應(yīng)該由此觸發(fā)一個click事件。 2.如果用戶按下了按鈕,然后在屏幕上拖動了一段距離,然后引起按鈕的touchEnd事件,此時我們也不應(yīng)該觸發(fā)click事件。 3.我們希望當(dāng)用戶按下按鈕時,能夠給這個按鈕一個按下的狀態(tài),從而使得其突出顯示。 |
| 我們能夠通過監(jiān)聽touchStart和touchMove事件解決前兩個問題。如果在按鈕上之前有touchStart事件,那么我們才會考慮在按鈕上的touchEnd事件。同樣,如果有一個touchMove事件且同touchStart的位置相比移動超過了某個閾值,那么我們就不應(yīng)該把這個touchEnd事件當(dāng)做click事件來處理。 我們也可以通過給按鈕添加一個onclick處理函數(shù)來解決第三個問題。那么做會恰好讓瀏覽器于把他當(dāng)做按鈕,而我們的touchEnd處理函數(shù)仍能夠確保這個按鈕響應(yīng)很快。同樣,一個onclick處理函數(shù)的存在,也能讓那些不支持touch事件的瀏覽器優(yōu)雅降級。 |
消除幽靈點擊 重新添加onclick處理函數(shù)給按鈕,會引發(fā)最后一個令人討厭的問題。但你輕觸按鈕時,一個click事件仍然會在300ms后被觸發(fā)。現(xiàn)在這個click處理函數(shù)就有被運行兩次的危險。這個可以通過在touchStart事件中調(diào)用preventDefault?很容易被解決。在touchStart事件中調(diào)用preventDefault方法將會阻止當(dāng)前的輕觸所引發(fā)的的click和scrolling。我們希望用戶可以滾動頁面,即使他們從按鈕的位置開始滾動,所以我們不認(rèn)為這是一個可接受的解決方案。我們想出的能解決幽靈點擊的方法叫做click buster(點擊破壞者)。我們所做的只是在頁面body中添加一個click的監(jiān)聽器,在捕獲階段監(jiān)聽。當(dāng)我們的監(jiān)聽器被觸發(fā),我們就會嘗試判定這個click事件是不是我們已經(jīng)當(dāng)做tap事件來處理的結(jié)果。如果是的話,我們就可以調(diào)用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;/* 構(gòu)建fastbutton與元素的引用并單擊處理程序. */this.FastButton =
function(element, handler, useCapture){// 收集功能調(diào)用清除事件 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;};/* 作為一個事件調(diào)度 */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位置的引用,然后開始監(jiān)聽touchMove和touchEnd事件。調(diào)用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;};/* 當(dāng)一個touchMove事件被觸發(fā),檢查用戶是否推動超過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,然后取消觸摸事件
}};/*觸發(fā)一個實際的click處理函數(shù),如果有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(){}/* 調(diào)用preventGhostClick來消除掉所有的在2.5s內(nèi)且在不超過保留的x,y坐標(biāo)周圍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事件,我們調(diào)用stopPropagation和preventDefault。調(diào)用preventDefault能夠阻止鏈接變?yōu)閍ctivated狀態(tài)。 */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) {// 不需要使用我們的自定義功能,因為我們只需要觸摸設(shè)備上點擊document.addEventListener('click', clickbuster.onClick,
true);clickbuster.coordinates =
[];}})(this);window.onload =
function(){new FastButton(document.getElementById('id2'),
function(){alert('click'
);});} View Code 總結(jié) 基于這一點,你應(yīng)該很容易就可以創(chuàng)建快速響應(yīng)的按鈕。通過一些奇特的方式,你能夠使這些按鈕看起來像是基于你的開發(fā)平臺的本地按鈕一樣。已經(jīng)有一些解決同樣問題的移動javascript庫可以使用了,但是我們還從未見過任何一個能夠提供click事件的優(yōu)雅降級或者幽靈點擊事件的解決方案的js庫。我們希望瀏覽器的開發(fā)者們能夠在將來的版本中,通過當(dāng)網(wǎng)站的縮放被禁止(通過使用viewport的meta標(biāo)簽)時,能直接觸發(fā)click事件的方式解決這個問題。實際上,這已經(jīng)是姜餅版安卓瀏覽器要解決的事情了。 |
英文原文:Creating Fast Buttons for Mobile Web Applications
轉(zhuǎn)載于:https://www.cnblogs.com/niubenbit/p/3623550.html
總結(jié)
以上是生活随笔為你收集整理的为移动端网页构造快速响应按钮的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。