railsのbxsliderのaタグが効かないときの対処法

# はじめに
スライドショーの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短い）とき、クリック処理がされないような記述になっている。

### 参考サイトの対応策

1. 「mousedown」で対策する
2. bxSliderのオプションの「touchEnabled」を’false’に設定する

### 感想

どっちもやだ。

### 理由

1. 操作感が変わる→気持ち悪い
2. スマホ上でフリックによるスライドはさせたい

# 解決するにいたった手順

1. gemのソースから`touchEnabled`を探す
2. `initTouch`呼び出してた。探す
3. `onTouchStart`をbindしてた。探す
4. いっぱい何か書いてる...。でも、 `onTouchStart`というよりは `onTouchEnd`みたいな関数が関係してそう。それ、bindされてた。探す
5. `distance`計算してるし、ここだ！
6. 無理矢理クリックイベントを発火させる方法調べる → 発見！(参考サイト参照) → 完成！  


※`onTouchStart`あたりから逐次`console.log(hoge);`で呼び出されている関数を確認していました。

# 該当コード

```ruby:app_name\vendor\bundle\ruby\2.4.0\gems\bxslider-rails-4.2.5.1\vendor\assets\javascripts\jquery.bxslider.js
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のスライド内のリンクが効かなくなった際の対処方](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/)  
[cly7796.net｜スワイプする要素の中にリンクがある場合の対応方法](http://cly7796.net/wp/javascript/if-there-is-a-link-in-the-swipe-elements/)
- `document.elementFromPoint(x, y).click();`で任意の座標でクリックイベントを発火させることを知りました。  
[Stack Overflow｜How to simulate a click by using x,y coordinates in JavaScript?](https://stackoverflow.com/questions/3277369/how-to-simulate-a-click-by-using-x-y-coordinates-in-javascript)
- 座標の取得方法はここで見つけました  
[gaaamiiのブログ｜function(e)のeってなんだ？]( https://shgam.hatenadiary.jp/entry/2013/06/27/022956)