anz blog

Swiper.jsでクリッカブルな要素が中にあると挙動が不安定になる

2022-04-05 #js

Swiper.jsはお手軽にカルーセルとかスライドショーとかを実現できるので、ありがたくつかわせてもらっているのですが、ちょっとした問題が発生したのでその内容と回避方法の話。

問題

Swiper で表示させる要素の中に、Clickable な要素(例えば a タグとか)があると、それをクリックした時の挙動が不安定という問題が発生しました。
正しくクリックが発火することもあれば、クリックは無視されてスワイプのほうが反応してしまったりと…なんどか粘ってクリックしてれば意図した挙動にあたるので、まったく使えないというわけえはないですが、
期待した挙動にならないっていうのはユーザーからしたらストレスになるので、なんとかしなきゃというはなしです。

ちなみに再現(?)コードはこんな感じです

<div class="swiper">
  <div class="swiper-wrapper">
    <div class="swiper-slide">
      <p>アイテム1</p>
      <a href="example.com">リンク</a>
    </div>
    <div class="swiper-slide">
      <p>アイテム2</p>
      <a href="example.com">リンク</a>
    </div>
  </div>
  <div class="swiper-button-prev"></div>
  <div class="swiper-button-next"></div>
</div>

これで、リンクをクリックした時の挙動が変だという話。

ちなみに、この問題は僕が観測した感じだと、Chrome で発生して、Safari では問題なかったです。

対応

どうやら、要素のスワイプ操作と要素の中のクリック操作とが競合してこういう挙動になっているみたいです。
なので、Clickable なものはスワイプ操作の対象外と指定してあげることでこの問題は回避できます。
具体的には class に swiper-no-swiping を指定してあげると良いです。
上記のコードを直すとこういう感じ。

<div class="swiper">
  <div class="swiper-wrapper">
    <div class="swiper-slide">
      <p>アイテム1</p>
      <a class="swiper-no-swiping" href="example.com">リンク</a>
    </div>
    <div class="swiper-slide">
      <p>アイテム2</p>
      <a class="swiper-no-swiping" href="example.com">リンク</a>
    </div>
  </div>
  <div class="swiper-button-prev"></div>
  <div class="swiper-button-next"></div>
</div>

これで、リンクをクリックしたときにスワイプ判定されることなく、ちゃんと遷移できるようになります。

課題

この対応で一応の解決はできるのですが、書かれている通り、対象要素をスワイプ操作外とするので、
上記の例でいうとリンク部分をスワイプしてアイテムを切り替えることができなくなります。

例だとリンクが一部テキストなので、それでも問題にはならないでしょうが、もしアイテム全体を覆うように a タグを設置したいとなった場合は、この方法だとスワイプ操作で切り替えることが全くできなくなりそうです。
その際も、一応 prev / next ボタンを配置したら切り替える事自体はできるようになるのですけれど、それで良いかどうかは採用しているプロジェクト次第となりそうです。

参考