はじめに
スライドショーのgem「bxslider」を使用していた際に、スライドショー内のリンクをクリックしても遷移しなかったので、直接コードをいじってなんとか解決しました。
そのフローを残しておきたいと思います。
開発環境
- windows7
- ruby 2.4.5p335 (2018-10-18 revision 65137) [x64-mingw32]
- Rails 5.2.3
- bxslider-rails 4.2.5.1
- jquery-rails 4.3.3
事象・検証状況
- スライドショー内のリンクをクリックしても遷移しない
- aタグをマウスオンすると遷移先URLが表示される
- aタグを覆う要素は存在しない
- レンダリング時のエラーなし
- 自身のコーディングに不備はない可能性が高い
- デベロッパーツールのコンソール上でもエラーなし
- JQueryでもエラーはない
- めっちゃ調べた。
- これっぽい。
カミナリ|bxSliderのスライド内のリンクが効かなくなった際の対処方
https://kaminarimagazine.com/web/2019/03/29/bxslider%E3%81%AE%E3%82%B9%E3%83%A9%E3%82%A4%E3%83%89%E5%86%85%E3%81%AE%E3%83%AA%E3%83%B3%E3%82%AF%E3%81%8C%E5%8A%B9%E3%81%8B%E3%81%AA%E3%81%8F%E3%81%AA%E3%81%A3%E3%81%9F%E9%9A%9B%E3%81%AE%E5%AF%BE/
解説
原因
スマホのタッチ・スワイプに対応させるためのオプションで、デフォルトが true
である、「touchEnabled」オプションにより、マウスオン(タッチ)時にドラッグ(スワイプ)操作判定となる。つまり、clickイベントとmouseleaveイベントが発火しない。
もう少し詳しく話すと、ページをスライドさせない(ドラッグ(スワイプ)距離がないor短い)とき、クリック処理がされないような記述になっている。
参考サイトの対応策
- 「mousedown」で対策する
- bxSliderのオプションの「touchEnabled」を’false’に設定する
感想
どっちもやだ。
理由
- 操作感が変わる→気持ち悪い
- スマホ上でフリックによるスライドはさせたい
解決するにいたった手順
- gemのソースから
touchEnabled
を探す -
initTouch
呼び出してた。探す -
onTouchStart
をbindしてた。探す - いっぱい何か書いてる...。でも、
onTouchStart
というよりはonTouchEnd
みたいな関数が関係してそう。それ、bindされてた。探す -
distance
計算してるし、ここだ! - 無理矢理クリックイベントを発火させる方法調べる → 発見!(参考サイト参照) → 完成!
※onTouchStart
あたりから逐次console.log(hoge);
で呼び出されている関数を確認していました。
該当コード
var onTouchEnd = function(e) {
if (slider.settings.mode === 'fade') {
#
# スライドショーのスタイルがfadeの時の処理
#
} else {
#
# 横スライド(horizontal)か縦スライド(vertical)の判定処理
#
if (!slider.settings.infiniteLoop && ((slider.active.index === 0 && distance > 0)|| (slider.active.last && distance < 0))) {
setPositionProperty(value, 'reset', 200);
} else {
if (Math.abs(distance) >= slider.settings.swipeThreshold) {
#
# ドラッグ距離 or スワイプ距離がスライド有効距離以上の場合のスライド処理
#
} else {
+ document.elementFromPoint(e.clientX, e.clientY).click();
setPositionProperty(value, 'reset', 200);
}
}
}
};
まとめ
初心者によるChromeのアップデートに対する不具合解消ですので、かなり付け焼刃的な解決法だったのかな、と思っています...。ちなみに、今回はfade形式のスライドショーはを使う予定がなかったので、コードを変更していませんが、# スライドショーのスタイルがfadeの時の処理
部分の類似部分を変更すればfadeでも正しく動作するはずです。
参考サイト
- エラーの概要をつかみました。
カミナリ|bxSliderのスライド内のリンクが効かなくなった際の対処方
cly7796.net|スワイプする要素の中にリンクがある場合の対応方法 -
document.elementFromPoint(x, y).click();
で任意の座標でクリックイベントを発火させることを知りました。
Stack Overflow|How to simulate a click by using x,y coordinates in JavaScript? - 座標の取得方法はここで見つけました
gaaamiiのブログ|function(e)のeってなんだ?