行動端touch拖動事件和click事件衝突問題解決

2022-09-28 12:00:55

通過一個懸浮球互動功能的案例來闡述問題,以及解決辦法。

實現效果

類似微信裡的懸浮窗效果,蘋果手機的懸浮球功能效果

  1. 可以點選拖動,然後吸附在視窗邊緣

  2. 點選懸浮球,可以跳轉介面,或者更改懸浮球的形態

準備

  1. 行動端使用 touch事件型別
  • touchstart當用戶在觸控平面上放置了一個觸點時觸發 (手指放到螢幕上)

  • touchmove當用戶在觸控平面上移動觸點時觸發 (手指在螢幕上滑動)

  • touchend當一個觸點被使用者從觸控平面上移除(擡起手指)

  • touchcancel終止觸控事件

多點觸控

  1. TouchEvent.targetTouches 唯讀

一個 TouchList 物件,是包含了如下觸點的 Touch 物件:觸控起始於當前事件的目標 element 上,並且仍然沒有離開觸控平面的觸點。

視口處於第四象限,原點在左上角

event.targetTouches.clientX // 觸控元素橫座標
event.targetTouches.clientY // 觸控元素縱座標
  1. TouchEvent.touches 唯讀

一個 TouchList 物件,包含了所有當前接觸觸控平面的觸點的 Touch 物件,無論它們的起始於哪個 element 上,也無論它們狀態是否發生了變化。

實現

通過設定懸浮球定位樣式,拖動的時候計算座標,然後動態的修改懸浮球的定位偏移量,結合transtion過渡效果,實現平滑的過渡

程式碼比較簡單,就不貼了。

問題

當給元素新增了touch事件之後,click事件就不會出發了,那麼怎麼模擬點選效果呢?

分析

在不瞭解觸控事件響應機制的時候,你可能會從計算觸控目標元素的時長或者計算觸控起始位置來判定點選行為,但是這兩種方式都不是最佳的,原因有以下幾點:

  1. 計算觸控時長比較麻煩

  2. 判斷移動距離不嚴謹,有可能拖動了一圈又回到初始位置

  3. 結合計算觸控時長和觸控元素起始位置兩種方式,邏輯比較複雜

下面看我是怎麼做的:

首先應該瞭解觸控行為的事件響應機制:

  • 如果有拖動行為,事件執行次序為:touchstart-> touchmove-> touchend

  • 沒有拖動行為,事件執行次序為:touchstart-> touchend

從上面的分析來看,我們可以從touchmove 入手,繼續往下看