生活随笔
收集整理的這篇文章主要介紹了
为移动端网页构造快速响应按钮
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
背景 在谷歌,我們不斷地推測手機網頁應用的可能性。像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
總結
以上是生活随笔為你收集整理的为移动端网页构造快速响应按钮的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。