一般情況下,如果沒有經(jīng)過特殊處理持舆,移動端瀏覽器在派發(fā)點擊事件的時候,通常會出現(xiàn)300ms左右的延遲伪窖。也就是說逸寓,當我們點擊頁面的時候移動端瀏覽器并不是立即作出反應,而是會等上一小會兒才會出現(xiàn)點擊的效果覆山。在移動WEB興起的初期竹伸,用戶對300ms的延遲感覺不明顯。但是簇宽,隨著用戶對交互體驗的要求越來越高勋篓,現(xiàn)今吧享,移動端300ms的點擊延遲逐漸變得明顯而無法忍受。
那么譬嚣,移動端300ms的點擊延遲是怎么來的呢耙蔑?
問題由來
這要追溯至 2007 年初。蘋果公司在發(fā)布首款 iPhone 前夕孤荣,遇到一個問題:當時的網(wǎng)站都是為大屏幕設備所設計的甸陌。于是蘋果的工程師們做了一些約定,應對 iPhone 這種小屏幕瀏覽桌面端站點的問題盐股。
這當中最出名的钱豁,當屬雙擊縮放(double tap to zoom),這也是會有上述 300 毫秒延遲的主要原因疯汁。
雙擊縮放牲尺,顧名思義,即用手指在屏幕上快速點擊兩次幌蚊,iOS 自帶的 Safari 瀏覽器會將網(wǎng)頁縮放至原始比例谤碳。 那么這和 300 毫秒延遲有什么聯(lián)系呢? 假定這么一個場景溢豆。用戶在 iOS Safari 里邊點擊了一個鏈接蜒简。由于用戶可以進行雙擊縮放或者雙擊滾動的操作,當用戶一次點擊屏幕之后漩仙,瀏覽器并不能立刻判斷用戶是確實要打開這個鏈接搓茬,還是想要進行雙擊操作。因此队他,iOS Safari 就等待 300 毫秒卷仑,以判斷用戶是否再次點擊了屏幕。 鑒于iPhone的成功麸折,其他移動瀏覽器都復制了 iPhone Safari 瀏覽器的多數(shù)約定锡凝,包括雙擊縮放,幾乎現(xiàn)在所有的移動端瀏覽器都有這個功能垢啼。之前人們剛剛接觸移動端的頁面窜锯,在欣喜的時候往往不會care這個300ms的延時問題,可是如今touch端界面如雨后春筍膊夹,用戶對體驗的要求也更高衬浑,這300ms帶來的卡頓慢慢變得讓人難以接受。
也就是說放刨,移動端瀏覽器會有一些默認的行為,比如雙擊縮放尸饺、雙擊滾動进统。這些行為助币,尤其是雙擊縮放,主要是為桌面網(wǎng)站在移動端的瀏覽體驗設計的螟碎。而在用戶對頁面進行操作的時候眉菱,移動端瀏覽器會優(yōu)先判斷用戶是否要觸發(fā)默認的行為。
那有什么辦法可以解決這個問題呢掉分?
瀏覽器開發(fā)商的解決方案
瀏覽器開發(fā)商要對移動端瀏覽器本身的設計進行改善俭缓,以提供長遠的解決方案。
目前酥郭,瀏覽器開發(fā)商的解決方案主要有一下三種方案:
方案一:禁用縮放
當HTML文檔頭部包含如下meta
標簽時:
<meta name="viewport" content="user-scalable=no">
<meta name="viewport" content="initial-scale=1,maximum-scale=1">
表明這個頁面是不可縮放的华坦,那雙擊縮放的功能就沒有意義了,此時瀏覽器可以禁用默認的雙擊縮放行為并且去掉300ms的點擊延遲不从。
這個方案有一個缺點惜姐,就是必須通過完全禁用縮放來達到去掉點擊延遲的目的,然而完全禁用縮放并不是我們的初衷椿息,我們只是想禁掉默認的雙擊縮放行為歹袁,這樣就不用等待300ms來判斷當前操作是否是雙擊。但是通常情況下寝优,我們還是希望頁面能通過雙指縮放來進行縮放操作条舔,比如放大一張圖片,放大一段很小的文字乏矾。
方案二:更改默認的視口寬度
一開始逞刷,為了讓桌面站點能在移動端瀏覽器正常顯示,移動端瀏覽器默認的視口寬度并不等于設備瀏覽器視窗寬度妻熊,而是要比設備瀏覽器視窗寬度大夸浅,通常是980px。我們可以通過以下標簽來設置視口寬度為設備寬度扔役。
<meta name="viewport" content="width=device-width">
因為雙擊縮放主要是用來改善桌面站點在移動端瀏覽體驗的帆喇,而隨著響應式設計的普及,很多站點都已經(jīng)對移動端坐過適配和優(yōu)化了亿胸,這個時候就不需要雙擊縮放了坯钦,如果能夠識別出一個網(wǎng)站是響應式的網(wǎng)站,那么移動端瀏覽器就可以自動禁掉默認的雙擊縮放行為并且去掉300ms的點擊延遲侈玄。如果設置了上述meta
標簽婉刀,那瀏覽器就可以認為該網(wǎng)站已經(jīng)對移動端做過了適配和優(yōu)化,就無需雙擊縮放操作了序仙。
這個方案相比方案一的好處在于突颊,它沒有完全禁用縮放,而只是禁用了瀏覽器默認的雙擊縮放行為,但用戶仍然可以通過雙指縮放操作來縮放頁面律秃。
方案三:CSS touch-action
網(wǎng)上很多文章把這個方案歸結為指針事件爬橡,這令我很疑惑。
以我的理解來看棒动,指針事件的提出并不是為了解決300ms點擊延遲的糙申,而是為了使用一個單獨的事件模型,對鼠標船惨、觸摸柜裸、觸控等多種輸入類型進行統(tǒng)一的處理。也就是說粱锐,移動瀏覽器不用再為不同的輸入設備設計不同的事件疙挺,網(wǎng)頁的開發(fā)者也不用再為不同輸入類型的設備寫不同的事件響應代碼,而是通過統(tǒng)一的指針事件就可以開發(fā)出跨不同輸入類型終端的應用卜范。
跟300ms點擊延遲相關的衔统,是touch-action
這個CSS屬性。這個屬性指定了相應元素上能夠觸發(fā)的用戶代理(也就是瀏覽器)的默認行為海雪。如果將該屬性值設置為touch-action: none
锦爵,那么表示在該元素上的操作不會觸發(fā)用戶代理的任何默認行為,就無需進行300ms的延遲判斷奥裸。
而設置這個CSS屬性與否险掀,指針事件應該都是可以工作的。所以湾宙,網(wǎng)上的文章令我很疑惑樟氢,希望有大神能給我指示~ 。侠鳄。~
現(xiàn)有的解決方案
要解決300ms點擊延遲的問題埠啃,從長遠來說,自然還是得瀏覽器開發(fā)商提供統(tǒng)一的最終的解決方案伟恶。但是碴开,到目前為止,以上三種方案并不能提供很好的兼容性博秫,對于方案一和方案二潦牛,Chrome是率先支持的,F(xiàn)irefox緊隨其后挡育,然而令Safari頭疼的是巴碗,它除了雙擊縮放還有雙擊滾動操作,如果采用這種兩種方案即寒,那勢必連雙擊滾動也要一起禁用橡淆;對于方案三召噩,IE是支持的,但是其他瀏覽器支持不完善明垢。具體請看這篇文章:移動端Click300毫秒點擊延遲的來龍去脈(轉)蚣常。
所以市咽,在瀏覽器開發(fā)商最終統(tǒng)一的解決方案出來之前痊银,我們還有一些基于Javascript的現(xiàn)成的解決方案可以用。
方案一:指針事件的polyfill
現(xiàn)在除了IE施绎,其他大部分瀏覽器都還不支持指針事件溯革。有一些JS庫,可以讓我們提前使用指針事件谷醉,比如
- Google 的 Polymer
- 微軟的 HandJS
- @Rich-Harris 的 Points
然而致稀,我們現(xiàn)在關心的不是指針事件,而是與300ms延遲相關的CSS屬性touch-action
俱尼。由于除了IE之外的大部分瀏覽器都不支持這個新的CSS屬性抖单,所以這些指針事件的polyfill必須通過某種方式去模擬支持這個屬性。一種方案是JS去請求解析所有的樣式表遇八,另一種方案是將touch-action
作為html標簽的屬性矛绘。
方案二:FastClick
FastClick 是 FT Labs 專門為解決移動端瀏覽器 300 毫秒點擊延遲問題所開發(fā)的一個輕量級的庫。FastClick的實現(xiàn)原理是在檢測到touchend事件的時候刃永,會通過DOM自定義事件立即出發(fā)模擬一個click事件货矮,并把瀏覽器在300ms之后的click事件阻止掉。
二斯够、點擊穿透問題
說完移動端點擊300ms延遲的問題囚玫,還不得不提一下移動端點擊穿透的問題《凉妫可能有人會想抓督,既然click點擊有300ms的延遲,那對于觸摸屏束亏,我們直接監(jiān)聽touchstart事件不就好了嗎铃在?
使用touchstart去代替click事件有兩個不好的地方。
第一:touchstart是手指觸摸屏幕就觸發(fā)枪汪,有時候用戶只是想滑動屏幕涌穆,卻觸發(fā)了touchstart事件,這不是我們想要的結果雀久;
第二:使用touchstart事件在某些場景下可能會出現(xiàn)點擊穿透的現(xiàn)象宿稀。
什么是點擊穿透?
假如頁面上有兩個元素A和B赖捌。B元素在A元素之上祝沸。我們在B元素的touchstart事件上注冊了一個回調函數(shù)矮烹,該回調函數(shù)的作用是隱藏B元素。我們發(fā)現(xiàn)罩锐,當我們點擊B元素奉狈,B元素被隱藏了,隨后涩惑,A元素觸發(fā)了click事件仁期。
這是因為在移動端瀏覽器,事件執(zhí)行的順序是touchstart > touchend > click竭恬。而click事件有300ms的延遲跛蛋,當touchstart事件把B元素隱藏之后,隔了300ms痊硕,瀏覽器觸發(fā)了click事件赊级,但是此時B元素不見了,所以該事件被派發(fā)到了A元素身上岔绸。如果A元素是一個鏈接理逊,那此時頁面就會意外地跳轉。
參考文章鏈接
移動端Click300毫秒點擊延遲的來龍去脈(轉)
移動端click事件延遲300ms到底是怎么回事盒揉,該如何解決晋被?
詳細解析-移動H5點擊穿透現(xiàn)象
作者:tsyeyuanfeng
鏈接:http://www.reibang.com/p/6e2b68a93c88
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯(lián)系作者獲得授權并注明出處预烙。