最近移動(dòng)端m站的開發(fā)中遇到了點(diǎn)擊穿透問題,就此總結(jié)一番。
先說下我遇到的問題,項(xiàng)目使用react框架捆等,并且引入了react-fastclick庫,可以解決click事件的穿透問題续室,但是對(duì)于下層是 a標(biāo)簽 的情況栋烤,依舊存在穿透問題,會(huì)觸發(fā)鏈接挺狰。
我的解決方法是把上層的事件放在了一個(gè)setTimeout(() => {}, 0)
中班缎。
goBack() {
setTimeout(() => {
browserHistory.goBack()
}, 0)
}
下面說一下點(diǎn)擊穿透問題是怎么來的。
點(diǎn)擊穿透是指她渴,在移動(dòng)端H5頁面中达址,當(dāng)點(diǎn)擊事件會(huì)切到一個(gè)新頁面時(shí)(比如返回上一頁面,或彈出彈窗頁面趁耗,或關(guān)閉遮罩層)沉唠,新頁面中相應(yīng)的位置如果有事件(或input等輸入框),就會(huì)被觸發(fā)苛败。
這是因?yàn)樵趐c頁面中满葛,一次點(diǎn)擊行為包括 mousedown -> click -> mouseup
,而在移動(dòng)端罢屈,則是touchstart -> touchmove -> touchend
嘀韧。
在移動(dòng)端,雖然沒有 mouse缠捌,依然會(huì)響應(yīng) mouse 事件锄贷,但是有個(gè)300ms 的時(shí)延译蒂。于是移動(dòng)端的一次點(diǎn)擊其實(shí)是這樣的:touchstart -> touchmove -> touchend -> 300ms ->mousedown -> click -> mouseup
。
之所以有時(shí)延谊却,是因?yàn)樵谶@ 300ms 中柔昼,移動(dòng)端會(huì)檢測(cè)是否有雙擊行為。
正因如此炎辨,在這 300ms 之中捕透,頁面變成了新的頁面,click 事件就會(huì)觸發(fā)成新頁面中的 click 事件了碴萧。
這種問題可以通過一些庫來解決乙嘀,比如fastclick庫,其實(shí)現(xiàn)思路是破喻,取消 click 事件(參看源碼 164-173 行)虎谢,用 touchend 模擬快速點(diǎn)擊行為(參看源碼 521-610 行)。其實(shí)就是在檢測(cè)到 touchend 事件的時(shí)候低缩,會(huì)通過 DOM 自定義事件立即出發(fā)模擬一個(gè) click 事件嘉冒,并把瀏覽器在 300ms 之后真正的 click 事件阻止掉曹货。
但正如文章開頭所講咆繁,fastclick 對(duì)于 a 標(biāo)簽的情況依然存在問題,仍需自行解決顶籽。
對(duì)于瀏覽器點(diǎn)擊事件更加詳盡的介紹玩般,可參考這篇文章,雖是遠(yuǎn)古文礼饱,耐心讀下來對(duì)夯實(shí)基礎(chǔ)會(huì)有很大的幫助坏为。