一直以為移動(dòng)端點(diǎn)擊事件會(huì)有300ms的延遲,原來只是我覺得,不應(yīng)該要我覺得[捂臉]
1) 為啥移動(dòng)端會(huì)有click延遲的說法?
谷歌開發(fā)者文檔 300ms tap delay, gone away
For many years, mobile browsers applied a 300-350ms delay between touchend and click while they waited to see if this was going to be a double-tap or not, since double-tap was a gesture to zoom into text.
即 移動(dòng)端要判斷是否是雙擊,所以單擊之后不能夠立刻觸發(fā)click,要等300ms,直到確認(rèn)不是雙擊了才觸發(fā)click。所以就導(dǎo)致了click有延遲。
這是移動(dòng)端瀏覽器的默認(rèn)行為,包括雙擊縮放、雙擊滾動(dòng)。這些行為,尤其是雙擊縮放,主要是為桌面網(wǎng)站在移動(dòng)端的瀏覽體驗(yàn)設(shè)計(jì)的。而在用戶對(duì)頁面進(jìn)行操作的時(shí)候,移動(dòng)端瀏覽器會(huì)優(yōu)先判斷用戶是否要觸發(fā)默認(rèn)的行為。
2)現(xiàn)在還有嗎?
答:可以沒有了。
在2014年的Chrome 32版本已經(jīng)把這個(gè)延遲去掉了,如果有一個(gè)meta標(biāo)簽:
<meta name="viewport" content="width=device-width">
即把viewport設(shè)置成設(shè)備的實(shí)際像素,那么就不會(huì)有這300ms的延遲,并且這個(gè)舉動(dòng)受到了IE/Firefox/Safari(IOS 9.3)的支持,也就是說現(xiàn)在的移動(dòng)端開發(fā)可以不用顧慮click會(huì)比較遲鈍的問題。
如果設(shè)置initial-scale=1.0,在chrome上是可以生效,但是Safari不會(huì):
<meta name**=**"viewport" content**=**"initial-scale=1.0">
還有第三種辦法就是設(shè)置CSS:
html{
touch-action: **manipulation**;
}
這樣也可以取消掉300ms的延遲,Chrome和Safari都可以生效。
3) 證明一下?
答: 哦。
!function(){
const html = document.documentElement;
let touchstartBeginTime = 0;
const log = (event) =>{
if(event.type === "touchstart") touchstartBeginTime = Date.now();
console.log(event.type, Date.now() - touchstartBeginTime);
}
html.onclick = log;
html.ontouchstart = log;
html.ontouchend = log;
html.ontouchmove = log;
html.onmouseover = log;
html.onmousedown = log;
html.onmouseup = log;
}();
meta包含 width=device-width or initial-scale=1.0
單擊事件觸發(fā)順序:

雙擊事件觸發(fā)順序:

meta不包含 width=device-width or initial-scale=1.0
單擊事件觸發(fā)順序:

雙擊事件觸發(fā)順序:

4)Tap事件是啥?
答: 在zepto和fastclick中所用的事件, 原生沒有tap事件。
可以按照 zapto 和fastclick 中的實(shí)現(xiàn)方式實(shí)現(xiàn)tap事件(實(shí)現(xiàn)方式不同), 基本比click 快20ms 左右,可能由于在click 之前還需觸發(fā)mouse事件吧。