📲

【JavaScript】スマートフォンで左右・上下のスワイプを検知してイベントを作成したい😭⇦超簡単に実装!iOS・Android対応🤗

2022/12/13に公開
2

はじめに

「スワイプ時に処理を実行したいけど、方法がわからない!」
「スワイプの検知はできるけど左右か上下に限定して作成したい🥺」

そんなことはありませんか?

今回は、スワイプイベントの実装方法から、左右・上下どちらかなど、方向を限定したスワイプイベントの実装方法も解説させていただきます。

この記事を見るメリット

  • スワイプイベントの実装方法がわかる
  • 左右・上下スワイプに限定して処理を実行することができるようになる
  • スワイプイベント実装時、最低限のスワイプ距離なども設定できるようになる

対象者

この記事は下記のような人を対象にしています。

  • プログラミング初学者
  • 駆け出しエンジニア
  • スワイプイベントを実装したい方
  • スワイプイベントを左右・上下に限定したい方
  • iOSとAndroid両方に対応して作成したい方

結論

スワイプを開始した座標と、スワイプを終了した座標から左右スワイプか上下スワイプかを判定しよう!

// タップ時の誤動作を防ぐためのスワイプ時の処理を実行しない最小距離
const minimumDistance = 30
// スワイプ開始時の座標
let startX = 0
let startY = 0
// スワイプ終了時の座標
let endX = 0
let endY = 0

// 解説①:移動を開始した座標を取得
window.addEventListener('touchstart', (e) =>  {
  startX = e.touches[0].pageX
  startY = e.touches[0].pageY
})

// 解説②:移動した座標を取得
window.addEventListener('touchmove', (e) =>  {
  endX = e.changedTouches[0].pageX
  endY = e.changedTouches[0].pageY
})


// 解説③:移動距離から左右or上下の処理を実行
window.addEventListener('touchend', (e) =>  {
  // スワイプ終了時にx軸とy軸の移動量を取得
  // 左スワイプに対応するためMath.abs()で+に変換
  const distanceX = Math.abs(endX - startX)
  const distanceY = Math.abs(endY - startY)

  // 左右のスワイプ距離の方が上下より長い && 小さなスワイプは検知しないようにする
  if (distanceX > distanceY && distanceX > minimumDistance) {
    // スワイプ後の動作
    console.log('左右スワイプ')
  }
  
  // 上下のスワイプ距離の方が左右より長い && 小さなスワイプは検知しないようにする
  if (distanceX < distanceY && distanceY > minimumDistance) {
    // スワイプ後の動作
    console.log('上下スワイプ')
  }
})

解説

ここからはコードの詳細や、記述を解説します!

解説①:移動を開始した座標を取得

touchesで指が触れた瞬間のさまざまなTouchオブジェクトの情報を取得することができます。
pageX, pageYは画面内ではなく、ページ内での距離です。

window.addEventListener('touchstart', (e) =>  {
  startX = e.touches[0].pageX
  startY = e.touches[0].pageY
})

解説②:移動した座標を取得

changedTouchesで変化したTouchオブジェクトの情報を取得することができます。

window.addEventListener('touchmove', (e) =>  {
  endX = e.changedTouches[0].pageX
  endY = e.changedTouches[0].pageY
})

解説③:移動距離から左右or上下の処理を実行

左右・上下のスワイプの判定の考え方としては、以下のようになります。

  • スワイプ開始地点とスワイプ終了地点の座標の間の距離の長さを比べて判定する
  • 左スワイプと上スワイプは距離を算出した時にマイナスの値になる
  • Math.absで正の数に変えれば、左スワイプと上スワイプも判定することができる
window.addEventListener('touchend', (e) =>  {
  const distanceX = Math.abs(endX - startX)
  const distanceY = Math.abs(endX - startY)

  // 左右のスワイプ距離の方が上下より長い && 小さなスワイプは検知しないようにする
  if (distanceX > distanceY && distanceX > minimumDistance) {
    // スワイプ後の動作
    console.log('左右スワイプ')
  }
  
  // 上下のスワイプ距離の方が左右より長い && 小さなスワイプは検知しないようにする
  if (distanceX < distanceY && distanceY > minimumDistance) {
    // スワイプ後の動作
    console.log('上下スワイプ')
  }
})

応用:Chromeの左右スワイプでの戻る・進む処理をしないようにする

Chromeでは左右スワイプで戻る・進むをすることができます。
ページを戻る・進むを止めたい場合、historyなどを使用すると思いますが、この左右スワイプの戻る・進むを止めることはできません😭

ではどうすればいいのか?

以下のように、左右スワイプ処理時にreturnを返すようにします!
すると、return false以降に実行される、戻る・進むの内部処理が実行されなくなります。

if (distanceX > distanceY && distanceX > minimumDistance) {
  return false
}

まとめ

  • addEventListenerを使用してイベントを作成しよう!
    • touchstart:スワイプ開始時
    • touchmove:スワイプ中
    • touchend:指が画面から離れた時

おわりに

スワイプイベントの実装方法から、左右・上下どちらかなど、方向を限定したスワイプイベントの実装方法まで解説させていただきました!

最後まで記事を見てくださりありがとうございました。
誤字や脱字、コードのリファクタリングできる箇所などがありましたらコメントくださるとありがたいです!
また、いいねをしてくださると、筆者が喜びます:)

Discussion

とうやんとうやん

ありがとうございます。勉強になりました。

1か所、間違いがありました。
const distanceY = Math.abs(endX - startY)

const distanceY = Math.abs(endY - startY)
ですね。

ふぃふぃ

ご指摘ありがとうございます!
typoですね。。。こちら修正させていただきました。