1、起因
雙擊縮放肪笋,因此產(chǎn)生了300ms延遲來判斷是不是雙擊月劈,問題也因此產(chǎn)生
2、問題
如果單擊鏈接時藤乙,需要等300ms后作出判斷猜揪,會給用戶卡頓的感覺,因此不行坛梁。
3而姐、解決方案
瀏覽器開發(fā)商解決方案:
- 方案一:禁用縮放
<meta name="viewport" content="user-scalable=no">
<meta name="viewport" content="initial-scale=1,maximum-scale=1">
表明這個頁面是不可縮放的,那雙擊縮放的功能就沒有意義了划咐,此時瀏覽器可以禁用默認(rèn)的雙擊縮放行為并且去掉300ms的點(diǎn)擊延遲拴念。
這個方案有一個缺點(diǎn),就是必須通過完全禁用縮放來達(dá)到去掉點(diǎn)擊延遲的目的褐缠,然而完全禁用縮放并不是我們的初衷政鼠,我們只是想禁掉默認(rèn)的雙擊縮放行為,這樣就不用等待300ms來判斷當(dāng)前操作是否是雙擊队魏。但是通常情況下公般,我們還是希望頁面能通過雙指縮放來進(jìn)行縮放操作,比如放大一張圖片胡桨,放大一段很小的文字官帘。
- 方案二:更改默認(rèn)的視口寬度
一開始,為了讓桌面站點(diǎn)能在移動端瀏覽器正常顯示昧谊,移動端瀏覽器默認(rèn)的視口寬度并不等于設(shè)備瀏覽器視窗寬度刽虹,而是要比設(shè)備瀏覽器視窗寬度大,通常是980px呢诬。我們可以通過以下標(biāo)簽來設(shè)置視口寬度為設(shè)備寬度涌哲。
<meta name="viewport" content="width=device-width">
因?yàn)殡p擊縮放主要是用來改善桌面站點(diǎn)在移動端瀏覽體驗(yàn)的,而隨著響應(yīng)式設(shè)計(jì)的普及馅巷,很多站點(diǎn)都已經(jīng)對移動端坐過適配和優(yōu)化了膛虫,這個時候就不需要雙擊縮放了,如果能夠識別出一個網(wǎng)站是響應(yīng)式的網(wǎng)站钓猬,那么移動端瀏覽器就可以自動禁掉默認(rèn)的雙擊縮放行為并且去掉300ms的點(diǎn)擊延遲稍刀。如果設(shè)置了上述meta標(biāo)簽,那瀏覽器就可以認(rèn)為該網(wǎng)站已經(jīng)對移動端做過了適配和優(yōu)化敞曹,就無需雙擊縮放操作了账月。
這個方案相比方案一的好處在于,它沒有完全禁用縮放澳迫,而只是禁用了瀏覽器默認(rèn)的雙擊縮放行為局齿,但用戶仍然可以通過雙指縮放操作來縮放頁面。
- 方案三:指針事件
指針事件是一個新的 web 事件系列橄登,相應(yīng)的規(guī)范旨在使用一個單獨(dú)的事件模型抓歼,對所有輸入類型讥此,包括鼠標(biāo) (mouse)、觸摸 (touch)谣妻、觸控 (stylus) 等萄喳,進(jìn)行統(tǒng)一的處理。
touch-action 屬性決定 “是否觸摸操作會觸發(fā)用戶代理的默認(rèn)行為蹋半。這包括但不限于雙指縮放等行為”他巨。從實(shí)際應(yīng)用的角度來看,touch-action 決定了用戶在點(diǎn)擊了目標(biāo)元素之后减江,是否能夠進(jìn)行雙指縮放或者雙擊縮放染突。因此,這也相當(dāng)完美地解決了 300 毫秒點(diǎn)擊延遲的問題辈灼。touch-action 的默認(rèn)值為 auto份企,將其置為 none 即可移除目標(biāo)元素的 300 毫秒延遲。
現(xiàn)有解決方案:
方案一:指針事件的polyfill
現(xiàn)在除了IE巡莹,其他大部分瀏覽器都還不支持指針事件薪棒。有一些JS庫,可以讓我們提前使用指針事件榕莺,比如
然而俐芯,我們現(xiàn)在關(guān)心的不是指針事件,而是與300ms延遲相關(guān)的CSS屬性touch-action
钉鸯。由于除了IE之外的大部分瀏覽器都不支持這個新的CSS屬性吧史,所以這些指針事件的polyfill必須通過某種方式去模擬支持這個屬性。一種方案是JS去請求解析所有的樣式表唠雕,另一種方案是將touch-action
作為html標(biāo)簽的屬性贸营。
方案二:FastClick
FastClick 是 FT Labs 專門為解決移動端瀏覽器 300 毫秒點(diǎn)擊延遲問題所開發(fā)的一個輕量級的庫。FastClick的實(shí)現(xiàn)原理是在檢測到touchend事件的時候岩睁,會通過DOM自定義事件立即出發(fā)模擬一個click事件钞脂,并把瀏覽器在300ms之后的click事件阻止掉。
點(diǎn)擊穿透
說完移動端點(diǎn)擊300ms延遲的問題捕儒,還不得不提一下移動端點(diǎn)擊穿透的問題冰啃。可能有人會想刘莹,既然click點(diǎn)擊有300ms的延遲阎毅,那對于觸摸屏点弯,我們直接監(jiān)聽touchstart事件不就好了嗎扇调?
使用touchstart去代替click事件有兩個不好的地方抢肛。
第一:touchstart是手指觸摸屏幕就觸發(fā)碳柱,有時候用戶只是想滑動屏幕,卻觸發(fā)了touchstart事件熬芜,這不是我們想要的結(jié)果士聪;
第二:使用touchstart事件在某些場景下可能會出現(xiàn)點(diǎn)擊穿透的現(xiàn)象。
什么是點(diǎn)擊穿透?
假如頁面上有兩個元素A和B灵寺。B元素在A元素之上。我們在B元素的touchstart事件上注冊了一個回調(diào)函數(shù)略板,該回調(diào)函數(shù)的作用是隱藏B元素毁枯。我們發(fā)現(xiàn),當(dāng)我們點(diǎn)擊B元素叮称,B元素被隱藏了种玛,隨后,A元素觸發(fā)了click事件赂韵。
這是因?yàn)樵谝苿佣藶g覽器挠蛉,事件執(zhí)行的順序是touchstart > touchend > click。而click事件有300ms的延遲谴古,當(dāng)touchstart事件把B元素隱藏之后,隔了300ms掰担,瀏覽器觸發(fā)了click事件,但是此時B元素不見了带饱,所以該事件被派發(fā)到了A元素身上。如果A元素是一個鏈接勺疼,那此時頁面就會意外地跳轉(zhuǎn)。