首頁  >  文章  >  web前端  >  JS中touchstart事件與click事件衝突的解決方法

JS中touchstart事件與click事件衝突的解決方法

亚连
亚连原創
2018-05-31 10:21:422133瀏覽

這篇文章主要為大家介紹了關於JS中touchstart事件與click事件衝突的解決方法,文中透過範例程式碼將解決的方法介紹的非常詳細,對大家的學習或工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧。

前言

行動互聯網是未來的發展趨勢,現在國內很多網路大佬都在爭取移動這一塊大餅,如微信及支付寶是目前比較成功的例子,當然還有各種APP和web運用。

下面這篇文章主要介紹了關於JS中touchstart事件與click事件衝突解決的相關內容,下面話不多說了,來一起看看詳細的介紹吧。

一· 業務場景的描述

#在完成的PC網站進行行動裝置適配時,我們想要網站在行動裝置上有更快的反應速度,以帶給使用者更好的體驗,此時,我們應該使用行動裝置專用的事件系統,例如,使用touchstart 事件取代click 事件。

為什麼這樣效果會更好呢?根據Google開發者文件中的描述:

行動裝置上的瀏覽器將會在 click 事件觸發時延遲 300ms ,以確保這是一個「點擊」事件而非「雙擊」事件。
而對於 touchstart 事件而言,則會在使用者手指觸碰螢幕的一瞬間觸發所綁定的事件。所以,使用 touchstart 取代 click 事件的意義在於,幫助使用者在每次點擊時節省 300ms 的時間。在頁面經常需要點擊,或點擊發生在動畫中,對動畫流暢度有較高要求的情境下,使用這種技術是非常必要的。

但是,讓我們回到我們的初始場景,在 PC端站點適配移動端時 我們不能簡單的進行 touchstart和 click 事件的替換,因為PC並不能識別 touchstart 事件。

二· 產生衝突的原因

#當然,我們可以同時綁定touchstart 和click事件,但這將會導致本篇文章解決的問題-- 這兩個事件在行動裝置上會發生衝突。

由於行動裝置能夠同時識別touchstart 和click 事件,因此當使用者點擊目標元素時,綁定在目標元素上的touchstart 事件與click 事件(約300ms後)會依次被觸發,也就是說,我們所綁定的回呼函數會被執行兩次! 。這顯然不是我們想要的結果。

三· 解決方案

#針對這樣的情境,有以下兩個解決方案:

(一)使用preventDefault

第一個解決方案是使用事件物件中的preventDefault 方法,preventDefault 方法的作用在於:阻止元素預設事件行為的發生,但有趣的是,當我們在目標元素同時綁定touchstart 和click 事件時,在touchstart 事件回呼函數中使用該方法,可以阻止後續click 事件的發生。

這從道理上是講不通的,畢竟,我們添加的click 事件並不是元素的“默認事件”,但它確實奏效了,或者說,被瀏覽器實現了,因此我們可以使用這個方法解決行動裝置上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!")
})

當你在瀏覽器上模擬行動裝置後點擊目標元素,只會在控制台看到touchstart event! 字段,很顯然,click 事件被成功阻止了。

總結

使用該方法的優點在於簡單粗暴,直接有效,能夠很好的實現我們的目標,但缺點在於, preventDefault 方法為阻止click 事件的方式是瀏覽器實作上的,而不是preventDefault 原理上的,這會帶來一些不確定性,雖然我暫時尚未發現該方法失效的具體場景。

(二)基於功能偵測綁定事件

我們可以透過判斷瀏覽器是否支援touchstart 事件來封裝元素的點擊事件,這樣客戶端會根據目前環境判定元素應該綁定的事件類型,程式碼如下:

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!")
})

上面是我整理給大家的,希望今後會對大家有幫助。

相關文章:

微信小程式中實作手指縮放圖片的範例程式碼

基於vue中css預先載入使用sass的配置方式詳解

Angular 4.x Ionic3踩坑之Ionic3.x pop反向傳值詳解

#

以上是JS中touchstart事件與click事件衝突的解決方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn