移動(dòng)端300ms點(diǎn)擊延遲和點(diǎn)擊穿透問題

一、移動(dòng)端300ms點(diǎn)擊延遲

一般情況下磺送,如果沒有經(jīng)過特殊處理,移動(dòng)端瀏覽器在派發(fā)點(diǎn)擊事件的時(shí)候灿意,通常會(huì)出現(xiàn)300ms左右的延遲估灿。也就是說,當(dāng)我們點(diǎn)擊頁面的時(shí)候移動(dòng)端瀏覽器并不是立即作出反應(yīng)缤剧,而是會(huì)等上一小會(huì)兒才會(huì)出現(xiàn)點(diǎn)擊的效果馅袁。在移動(dòng)WEB興起的初期,用戶對(duì)300ms的延遲感覺不明顯荒辕。但是汗销,隨著用戶對(duì)交互體驗(yàn)的要求越來越高,現(xiàn)今抵窒,移動(dòng)端300ms的點(diǎn)擊延遲逐漸變得明顯而無法忍受大溜。

那么,移動(dòng)端300ms的點(diǎn)擊延遲是怎么來的呢估脆?

問題由來
這要追溯至 2007 年初钦奋。蘋果公司在發(fā)布首款 iPhone 前夕,遇到一個(gè)問題:當(dāng)時(shí)的網(wǎng)站都是為大屏幕設(shè)備所設(shè)計(jì)的疙赠。于是蘋果的工程師們做了一些約定付材,應(yīng)對(duì) iPhone 這種小屏幕瀏覽桌面端站點(diǎn)的問題。

這當(dāng)中最出名的圃阳,當(dāng)屬雙擊縮放(double tap to zoom)厌衔,這也是會(huì)有上述 300 毫秒延遲的主要原因。

雙擊縮放捍岳,顧名思義富寿,即用手指在屏幕上快速點(diǎn)擊兩次睬隶,iOS 自帶的 Safari 瀏覽器會(huì)將網(wǎng)頁縮放至原始比例。 那么這和 300 毫秒延遲有什么聯(lián)系呢页徐? 假定這么一個(gè)場(chǎng)景苏潜。用戶在 iOS Safari 里邊點(diǎn)擊了一個(gè)鏈接。由于用戶可以進(jìn)行雙擊縮放或者雙擊滾動(dòng)的操作变勇,當(dāng)用戶一次點(diǎn)擊屏幕之后恤左,瀏覽器并不能立刻判斷用戶是確實(shí)要打開這個(gè)鏈接,還是想要進(jìn)行雙擊操作搀绣。因此飞袋,iOS Safari 就等待 300 毫秒,以判斷用戶是否再次點(diǎn)擊了屏幕链患。 鑒于iPhone的成功巧鸭,其他移動(dòng)瀏覽器都復(fù)制了 iPhone Safari 瀏覽器的多數(shù)約定,包括雙擊縮放麻捻,幾乎現(xiàn)在所有的移動(dòng)端瀏覽器都有這個(gè)功能纲仍。之前人們剛剛接觸移動(dòng)端的頁面,在欣喜的時(shí)候往往不會(huì)care這個(gè)300ms的延時(shí)問題芯肤,可是如今touch端界面如雨后春筍,用戶對(duì)體驗(yàn)的要求也更高压鉴,這300ms帶來的卡頓慢慢變得讓人難以接受崖咨。

也就是說,移動(dòng)端瀏覽器會(huì)有一些默認(rèn)的行為油吭,比如雙擊縮放击蹲、雙擊滾動(dòng)。這些行為婉宰,尤其是雙擊縮放歌豺,主要是為桌面網(wǎng)站在移動(dòng)端的瀏覽體驗(yàn)設(shè)計(jì)的。而在用戶對(duì)頁面進(jìn)行操作的時(shí)候心包,移動(dòng)端瀏覽器會(huì)優(yōu)先判斷用戶是否要觸發(fā)默認(rèn)的行為类咧。

那有什么辦法可以解決這個(gè)問題呢?

瀏覽器開發(fā)商的解決方案

瀏覽器開發(fā)商要對(duì)移動(dòng)端瀏覽器本身的設(shè)計(jì)進(jìn)行改善蟹腾,以提供長(zhǎng)遠(yuǎn)的解決方案痕惋。

目前,瀏覽器開發(fā)商的解決方案主要有一下三種方案:
方案一:禁用縮放
當(dāng)HTML文檔頭部包含如下meta標(biāo)簽時(shí):

<meta name="viewport" content="user-scalable=no">
<meta name="viewport" content="initial-scale=1,maximum-scale=1">

表明這個(gè)頁面是不可縮放的娃殖,那雙擊縮放的功能就沒有意義了值戳,此時(shí)瀏覽器可以禁用默認(rèn)的雙擊縮放行為并且去掉300ms的點(diǎn)擊延遲。
這個(gè)方案有一個(gè)缺點(diǎn)炉爆,就是必須通過完全禁用縮放來達(dá)到去掉點(diǎn)擊延遲的目的堕虹,然而完全禁用縮放并不是我們的初衷卧晓,我們只是想禁掉默認(rèn)的雙擊縮放行為,這樣就不用等待300ms來判斷當(dāng)前操作是否是雙擊赴捞。但是通常情況下逼裆,我們還是希望頁面能通過雙指縮放來進(jìn)行縮放操作,比如放大一張圖片螟炫,放大一段很小的文字波附。

方案二:更改默認(rèn)的視口寬度
一開始,為了讓桌面站點(diǎn)能在移動(dòng)端瀏覽器正常顯示昼钻,移動(dòng)端瀏覽器默認(rèn)的視口寬度并不等于設(shè)備瀏覽器視窗寬度掸屡,而是要比設(shè)備瀏覽器視窗寬度大,通常是980px然评。我們可以通過以下標(biāo)簽來設(shè)置視口寬度為設(shè)備寬度仅财。

<meta name="viewport" content="width=device-width">

因?yàn)殡p擊縮放主要是用來改善桌面站點(diǎn)在移動(dòng)端瀏覽體驗(yàn)的,而隨著響應(yīng)式設(shè)計(jì)的普及碗淌,很多站點(diǎn)都已經(jīng)對(duì)移動(dòng)端坐過適配和優(yōu)化了盏求,這個(gè)時(shí)候就不需要雙擊縮放了,如果能夠識(shí)別出一個(gè)網(wǎng)站是響應(yīng)式的網(wǎng)站亿眠,那么移動(dòng)端瀏覽器就可以自動(dòng)禁掉默認(rèn)的雙擊縮放行為并且去掉300ms的點(diǎn)擊延遲碎罚。如果設(shè)置了上述meta標(biāo)簽,那瀏覽器就可以認(rèn)為該網(wǎng)站已經(jīng)對(duì)移動(dòng)端做過了適配和優(yōu)化纳像,就無需雙擊縮放操作了荆烈。
這個(gè)方案相比方案一的好處在于,它沒有完全禁用縮放竟趾,而只是禁用了瀏覽器默認(rèn)的雙擊縮放行為憔购,但用戶仍然可以通過雙指縮放操作來縮放頁面。

方案三:CSS touch-action
網(wǎng)上很多文章把這個(gè)方案歸結(jié)為指針事件岔帽,這令我很疑惑玫鸟。

以我的理解來看,指針事件的提出并不是為了解決300ms點(diǎn)擊延遲的犀勒,而是為了使用一個(gè)單獨(dú)的事件模型屎飘,對(duì)鼠標(biāo)、觸摸贾费、觸控等多種輸入類型進(jìn)行統(tǒng)一的處理枚碗。也就是說,移動(dòng)瀏覽器不用再為不同的輸入設(shè)備設(shè)計(jì)不同的事件铸本,網(wǎng)頁的開發(fā)者也不用再為不同輸入類型的設(shè)備寫不同的事件響應(yīng)代碼肮雨,而是通過統(tǒng)一的指針事件就可以開發(fā)出跨不同輸入類型終端的應(yīng)用。

跟300ms點(diǎn)擊延遲相關(guān)的箱玷,是touch-action這個(gè)CSS屬性怨规。這個(gè)屬性指定了相應(yīng)元素上能夠觸發(fā)的用戶代理(也就是瀏覽器)的默認(rèn)行為陌宿。如果將該屬性值設(shè)置為touch-action: none,那么表示在該元素上的操作不會(huì)觸發(fā)用戶代理的任何默認(rèn)行為波丰,就無需進(jìn)行300ms的延遲判斷壳坪。

而設(shè)置這個(gè)CSS屬性與否,指針事件應(yīng)該都是可以工作的掰烟。所以爽蝴,網(wǎng)上的文章令我很疑惑,希望有大神能給我指示~ 纫骑。蝎亚。~

現(xiàn)有的解決方案

要解決300ms點(diǎn)擊延遲的問題,從長(zhǎng)遠(yuǎn)來說先馆,自然還是得瀏覽器開發(fā)商提供統(tǒng)一的最終的解決方案发框。但是,到目前為止煤墙,以上三種方案并不能提供很好的兼容性梅惯,對(duì)于方案一和方案二,Chrome是率先支持的仿野,F(xiàn)irefox緊隨其后铣减,然而令Safari頭疼的是,它除了雙擊縮放還有雙擊滾動(dòng)操作脚作,如果采用這種兩種方案葫哗,那勢(shì)必連雙擊滾動(dòng)也要一起禁用;對(duì)于方案三鳖枕,IE是支持的魄梯,但是其他瀏覽器支持不完善桨螺。具體請(qǐng)看這篇文章:移動(dòng)端Click300毫秒點(diǎn)擊延遲的來龍去脈(轉(zhuǎn))宾符。

所以,在瀏覽器開發(fā)商最終統(tǒng)一的解決方案出來之前灭翔,我們還有一些基于Javascript的現(xiàn)成的解決方案可以用魏烫。

方案一:指針事件的polyfill
現(xiàn)在除了IE,其他大部分瀏覽器都還不支持指針事件肝箱。有一些JS庫哄褒,可以讓我們提前使用指針事件,比如

然而煌张,我們現(xiàn)在關(guān)心的不是指針事件呐赡,而是與300ms延遲相關(guān)的CSS屬性touch-action。由于除了IE之外的大部分瀏覽器都不支持這個(gè)新的CSS屬性骏融,所以這些指針事件的polyfill必須通過某種方式去模擬支持這個(gè)屬性链嘀。一種方案是JS去請(qǐng)求解析所有的樣式表萌狂,另一種方案是將touch-action作為html標(biāo)簽的屬性。

方案二:FastClick
FastClickFT Labs 專門為解決移動(dòng)端瀏覽器 300 毫秒點(diǎn)擊延遲問題所開發(fā)的一個(gè)輕量級(jí)的庫怀泊。FastClick的實(shí)現(xiàn)原理是在檢測(cè)到touchend事件的時(shí)候茫藏,會(huì)通過DOM自定義事件立即出發(fā)模擬一個(gè)click事件,并把瀏覽器在300ms之后的click事件阻止掉霹琼。

二务傲、點(diǎn)擊穿透問題

說完移動(dòng)端點(diǎn)擊300ms延遲的問題,還不得不提一下移動(dòng)端點(diǎn)擊穿透的問題枣申∈燮希可能有人會(huì)想,既然click點(diǎn)擊有300ms的延遲糯而,那對(duì)于觸摸屏天通,我們直接監(jiān)聽touchstart事件不就好了嗎?
使用touchstart去代替click事件有兩個(gè)不好的地方熄驼。
第一:touchstart是手指觸摸屏幕就觸發(fā)像寒,有時(shí)候用戶只是想滑動(dòng)屏幕,卻觸發(fā)了touchstart事件瓜贾,這不是我們想要的結(jié)果诺祸;
第二:使用touchstart事件在某些場(chǎng)景下可能會(huì)出現(xiàn)點(diǎn)擊穿透的現(xiàn)象。

什么是點(diǎn)擊穿透祭芦?
假如頁面上有兩個(gè)元素A和B筷笨。B元素在A元素之上。我們?cè)贐元素的touchstart事件上注冊(cè)了一個(gè)回調(diào)函數(shù)龟劲,該回調(diào)函數(shù)的作用是隱藏B元素胃夏。我們發(fā)現(xiàn),當(dāng)我們點(diǎn)擊B元素昌跌,B元素被隱藏了仰禀,隨后,A元素觸發(fā)了click事件蚕愤。

這是因?yàn)樵谝苿?dòng)端瀏覽器答恶,事件執(zhí)行的順序是touchstart > touchend > click。而click事件有300ms的延遲萍诱,當(dāng)touchstart事件把B元素隱藏之后悬嗓,隔了300ms,瀏覽器觸發(fā)了click事件裕坊,但是此時(shí)B元素不見了包竹,所以該事件被派發(fā)到了A元素身上。如果A元素是一個(gè)鏈接,那此時(shí)頁面就會(huì)意外地跳轉(zhuǎn)周瞎。

參考文章鏈接

移動(dòng)端Click300毫秒點(diǎn)擊延遲的來龍去脈(轉(zhuǎn))
移動(dòng)端click事件延遲300ms到底是怎么回事悟狱,該如何解決?
詳細(xì)解析-移動(dòng)H5點(diǎn)擊穿透現(xiàn)象

招聘

前端工程師-抖音/火山

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末堰氓,一起剝皮案震驚了整個(gè)濱河市挤渐,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌双絮,老刑警劉巖浴麻,帶你破解...
    沈念sama閱讀 219,039評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異囤攀,居然都是意外死亡软免,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門焚挠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來膏萧,“玉大人,你說我怎么就攤上這事蝌衔¢环海” “怎么了?”我有些...
    開封第一講書人閱讀 165,417評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵噩斟,是天一觀的道長(zhǎng)曹锨。 經(jīng)常有香客問我,道長(zhǎng)剃允,這世上最難降的妖魔是什么沛简? 我笑而不...
    開封第一講書人閱讀 58,868評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮斥废,結(jié)果婚禮上椒楣,老公的妹妹穿的比我還像新娘。我一直安慰自己牡肉,他們只是感情好捧灰,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,892評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著荚板,像睡著了一般凤壁。 火紅的嫁衣襯著肌膚如雪吩屹。 梳的紋絲不亂的頭發(fā)上跪另,一...
    開封第一講書人閱讀 51,692評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音煤搜,去河邊找鬼免绿。 笑死,一個(gè)胖子當(dāng)著我的面吹牛擦盾,可吹牛的內(nèi)容都是我干的嘲驾。 我是一名探鬼主播淌哟,決...
    沈念sama閱讀 40,416評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼辽故!你這毒婦竟也來了徒仓?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,326評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤誊垢,失蹤者是張志新(化名)和其女友劉穎掉弛,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體喂走,經(jīng)...
    沈念sama閱讀 45,782評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡殃饿,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,957評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了芋肠。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片乎芳。...
    茶點(diǎn)故事閱讀 40,102評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖帖池,靈堂內(nèi)的尸體忽然破棺而出奈惑,到底是詐尸還是另有隱情,我是刑警寧澤睡汹,帶...
    沈念sama閱讀 35,790評(píng)論 5 346
  • 正文 年R本政府宣布携取,位于F島的核電站,受9級(jí)特大地震影響帮孔,放射性物質(zhì)發(fā)生泄漏雷滋。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,442評(píng)論 3 331
  • 文/蒙蒙 一文兢、第九天 我趴在偏房一處隱蔽的房頂上張望晤斩。 院中可真熱鬧,春花似錦姆坚、人聲如沸澳泵。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽兔辅。三九已至,卻和暖如春击喂,著一層夾襖步出監(jiān)牢的瞬間维苔,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工懂昂, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留介时,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,332評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像沸柔,于是被迫代替她去往敵國(guó)和親循衰。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,044評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容