JS中touchstart事件與click事件沖突的解決方法
前言
移動互聯(lián)網(wǎng)是未來的發(fā)展趨勢,現(xiàn)在國內(nèi)很多互聯(lián)網(wǎng)大佬都在爭取移動這一塊大餅,如微信及支付寶是目前比較成功的例子,當然還有各種APP和web運用。
下面這篇文章主要介紹了關(guān)于JS中touchstart事件與click事件沖突解決的相關(guān)內(nèi)容,下面話不多說了,來一起看看詳細的介紹吧。
一 · 業(yè)務(wù)場景的描述
在對已完成的PC站點進行移動端適配時,我們想要站點在移動設(shè)備上有更快的響應(yīng)速度,以帶給用戶更好的體驗,此時,我們應(yīng)該使用移動設(shè)備專用的事件系統(tǒng),例如,使用 touchstart 事件代替 click 事件。
為什么這樣效果會更好呢?根據(jù)Google開發(fā)者文檔中的描述:
移動設(shè)備上的瀏覽器將會在 click 事件觸發(fā)時延遲 300ms ,以確保這是一個“單擊”事件而非“雙擊”事件。
而對于 touchstart 事件而言,則會在用戶手指觸碰屏幕的一瞬間觸發(fā)所綁定的事件。所以,使用 touchstart 替換 click 事件的意義在于,幫助用戶在每次點擊時節(jié)省 300ms 的時間。在頁面頻繁需要點擊,或者點擊發(fā)生在動畫中,對動畫流暢度有較高要求的情境下,使用這種技術(shù)是非常必要的。
但是,讓我們回到我們的初始場景,在 PC端站點適配移動端時 我們不能簡單的進行 touchstart和 click 事件的替換,因為PC并不能識別 touchstart 事件。
二 · 產(chǎn)生沖突的原因
當然,我們可以給某個元素同時綁定 touchstart 和 click 事件,但這將會導致本篇文章解決的問題 -- 這兩個事件在移動設(shè)備上會發(fā)生沖突。
由于移動設(shè)備能夠同時識別 touchstart 和 click 事件,因此當用戶點擊目標元素時,綁定在目標元素上的 touchstart 事件與 click 事件(約300ms后)會依次被觸發(fā),也就是說,我們所綁定的回調(diào)函數(shù)會被執(zhí)行兩次!。這顯然不是我們想要的結(jié)果。
三 · 解決方案
針對這樣的情境,有以下兩種解決方案:
(一)使用 preventDefault
第一種解決方案是使用事件對象中的 preventDefault 方法,preventDefault 方法的作用在于:阻止元素默認事件行為的發(fā)生,但有意思的是,當我們在目標元素同時綁定 touchstart 和 click 事件時,在 touchstart 事件回調(diào)函數(shù)中使用該方法,可以阻止后續(xù) click 事件的發(fā)生。
這從道理上是講不通的,畢竟,我們添加的 click 事件并不是元素的“默認事件”,但它確實奏效了,或者說,被瀏覽器實現(xiàn)了,因此我們可以使用該方法解決移動設(shè)備上 touchstart 事件與 click 事件的沖突問題,具體代碼如下:
const Button = document.getElementById("targetButton") Button.addEventListener("touchstart", e => { e.preventDefault() console.log("touchstart event!") }) Button.addEventListener("click", e => { e.preventDefault() console.log("click event!") })
當你在瀏覽器上模擬移動設(shè)備后點擊目標元素,只會在控制臺看到 touchstart event! 字段,很顯然,click 事件被成功阻止了。
總結(jié)
使用該方法的優(yōu)點在于簡單粗暴,直接有效,能夠很好的實現(xiàn)我們的目標,但缺點在于, preventDefault 方法為阻止 click 事件的方式是瀏覽器實現(xiàn)上的,而不是 preventDefault 原理上的,這會帶來一些不確定性,雖然我暫時尚未發(fā)現(xiàn)該方法失效的具體場景。
(二)基于功能檢測綁定事件
我們可以通過判斷瀏覽器是否支持 touchstart 事件來封裝元素的點擊事件,這樣客戶端會根據(jù)當前環(huán)境判定元素應(yīng)該綁定的事件類型,代碼如下:
const Button = document.getElementById("targetButton") const clickEvent = (function() { if ('ontouchstart' in document.documentElement === true) return 'touchstart'; else return 'click'; })(); Button.addEventListener(clickEvent, e => { console.log("things happened!") })
總結(jié)
該方法的優(yōu)點在于,我們通過增加一次判斷,為元素減少了一個不必要的事件綁定,從而避免了 touchstart 與 click 事件的沖突問題。這種方法避免了我們書寫兩次同樣的代碼,并且相較于第一種方法更加符合邏輯,因此是我所推薦的。
好了,以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
相關(guān)文章
微信小程序用戶授權(quán)獲取手機號(getPhoneNumber)
這篇文章主要給大家介紹了關(guān)于微信小程序用戶授權(quán)獲取手機號的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-03-03js和jquery批量綁定事件傳參數(shù)一(新豬豬原創(chuàng))
js綁定事件傳參,javascript綁定事件傳參數(shù),jquery綁定事件傳參數(shù)2010-06-06layui table 列寬百分比顯示的實現(xiàn)方法
今天小編就為大家分享一篇layui table 列寬百分比顯示的實現(xiàn)方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-09-09