文章目錄
- 一、移動端點選産生300 ms的延遲
-
- 解決方案
-
- 方案一:禁用縮放(HTML文檔頭部設定meta标簽)
- 方案二:更改預設的視口寬度
- 方案三:CSS touch-action
- 方案四:FastClick
- 方案五:使用touchstart替代click
- 二、點選穿透
-
- 什麼是點選穿透,點選穿透為什麼會發生
- 什麼時候會觸發點選穿透
- 解決方案
-
- 延遲蒙層的消失時間
- CSS touch-action
- 使用FastClick
- 參考連結
一、移動端點選産生300 ms的延遲
300ms延遲是指當我們點選頁面的時候移動端浏覽器并不是立即作出反應,而是會等上300ms才會出現點選的效果。
而設定這300ms的意義在于判斷使用者的輕按兩下行為。移動端浏覽器會有一些預設的行為,比如輕按兩下縮放、輕按兩下滾動。這些行為,尤其是輕按兩下縮放,主要是為桌面網站在移動端的浏覽體驗設計的。
在移動web的興起初期,人們對這個問題的感覺并不明顯,但随着使用者對互動體驗的要求越來越高,現今,移動端300ms的點選延遲逐漸變得明顯而無法忍受。
解決方案
方案一:禁用縮放(HTML文檔頭部設定meta标簽)
<meta name="viewport" content="user-scalable=no">
<meta name="viewport" content="initial-scale=1,maximum-scale=1">
這種方法的缺點顯而易見,我們犧牲了縮放的功能。但實際需求中,我們還是希望能通過雙指還實作縮放的。我們不想要的隻是輕按兩下縮放行為。
方案二:更改預設的視口寬度
設定視口寬度為裝置寬度:
如果設定了上述meta标簽,那浏覽器就可以認為該網站已經對移動端做過了适配和優化,就無需輕按兩下縮放操作了。
這個方案相比方案一的好處在于,它沒有完全禁用縮放,而隻是禁用了浏覽器預設的輕按兩下縮放行為,但使用者仍然可以通過雙指縮放操作來縮放頁面。
方案三:CSS touch-action
CSS屬性
touch-action
用于設定觸摸屏使用者如何操縱元素的區域(例如,浏覽器内置的縮放功能)。
如果将該屬性值設定為
touch-action: none
,那麼表示在該元素上的操作不會觸發使用者代理的任何預設行為,就無需進行300ms的延遲判斷。
由于除了IE之外的大部分浏覽器都不支援這個新的CSS屬性,是以指針事件的polyfill必須通過某種方式去模拟支援這個屬性。一種方案是JS去請求解析所有的樣式表,另一種方案是将
touch-action
作為html标簽的屬性。
Polyfill 是一塊代碼(通常是 Web 上的 JavaScript),用來為舊浏覽器提供它沒有原生支援的較新的功能。
方案四:FastClick
FastClick 是 FT Labs 專門為解決移動端浏覽器 300 毫秒點選延遲問題所開發的一個輕量級的庫。
FastClick的實作原理是在檢測到touchend事件的時候,會通過DOM自定義事件立即出發模拟一個click事件,并把浏覽器在300ms之後的click事件阻止掉。
//引入fastclick
<script src="js/fastclick.min.js"></script>
// 原生js初始化
if ('addEventListener' in document) {
document.addEventListener('DOMContentLoaded', function() {
FastClick.attach(document.body);
}, false);
}
方案五:使用touchstart替代click
可能有人會想,既然click點選有300ms的延遲,那對于觸摸屏,我們直接監聽touchstart事件不就好了嗎?
事實上,使用touchstart去代替click事件有兩個不好的地方。
第一:touchstart是手指觸摸螢幕就觸發,有時候使用者隻是想滑動螢幕,卻觸發了touchstart事件,這不是我們想要的結果;
第二:使用touchstart事件在某些場景下可能會出現點選穿透的現象。下面講一講點選穿透。
二、點選穿透
什麼是點選穿透,點選穿透為什麼會發生
假如頁面上有兩個元素A和B。B元素在A元素之上。我們在B元素的
touchstart
事件上注冊了一個回調函數,該回調函數的作用是隐藏B元素。我們發現,當我們點選B元素,B元素被隐藏了,随後,A元素觸發了
click
事件。當然前提是A元素上綁定了
click
事件,或者說,A元素是個連結
<a>
、輸入框
<input>
等。
這是因為在移動端浏覽器,事件執行的順序是
touchstart > touchend > click
。而click事件有300ms的延遲,當
touchstart
事件把B元素隐藏之後,隔了300ms,浏覽器觸發了
click
事件,但是此時B元素不見了,是以該事件被派發到了A元素身上。如果A元素是一個連結,那此時頁面就會意外地跳轉。
什麼時候會觸發點選穿透
click隻是在移動端有300ms的延遲,是以,在移動端開發時,混用click和touch會導緻穿透事件。
解決方案
延遲蒙層的消失時間
對于設定蒙層的穿透,可以将這個蒙層消失的時間後移350ms,當然為了不讓使用者感覺到卡頓,可以先設定這個蒙層的
opacity
透明度為0,然後等350ms後,再設定
display:none
。
CSS touch-action
和之前說到的一樣,将
touch-action
設定為
none
,使被覆寫元素的click事件無法發生。當然我們需要在350ms之後解除這個鎖定,将
touch-action
恢複為
auto
。
這種方法的缺點就在于相容性問題。
使用FastClick
使用fastclick庫,從此所有的點選事件都使用click,而且不存在300ms延遲。當然也就沒有了點選穿透問題。
fastclick的用法上面也有談到。
參考連結
移動端點選300ms延遲問題和解決
點選穿透事件原因及解決辦法
Polyfill