TurbolinksのせいでJSが発火しない問題

f:id:endoakak:20200807190651j:plain

アプリ製作中にJavaScriptがうまく発火しなくて、うんうん唸りながら調べたところ、Turbolinksというやつが問題でした。

Turbolinksとは

簡単にいうと、リンクを押した時に読み込みをせずに素早く次のページを表示してくれるツールです。Rails6では標準で導入されているgemです。

もう少し詳しめにいうと、まず<a href>がクリックされた時に、それに従ってブラウザが動こうとするのを妨害します。そして、HistoryAPIというものを使ってURLを変え、XMLHttpRequestで新しいページをリクエストします。新しく得られたHTMLのbody要素を古いページのbody要素と入れ替えて、head要素とつなげることで、リンク先のページを表示します。

詳しいことはここに。

https://github.com/turbolinks/turbolinks

javascriptなどを読み込まずにHTMLのbody要素だけを取得して入れ替えているので、普通にリンク先に遷移するより早いみたいです。

Turbolinksの問題

いくつかあるみたいですが、今回私が直面したのは、javascriptが発火してほしいのに発火しない問題。Turbolinksを使っていると、以下のような記述ではリンクを押して移動しても発火しないみたいです。

window.addEventListener("load", function() {
  // 処理
}

loadは起きてないということらしいですね。

解決策1

Turbolinksを使っていてもturbolinks:loadにすればイベントが発火するみたいです。

window.addEventListener("turbolinks:load", function() {
  // 処理
}

結構時間かけて悩んだ割に簡単。
ただし今回はこれでうまく行きましたが、また別の問題が発生するかもしれません。

解決策2

こちらも簡単です。Turbolinksを無効化します。

app/javascript/packsapplication.jsに下のような記述があるので、コメントアウトしてしまえばOKです。

// require("turbolinks").start()

必須な機能ではないので無効化しても困らなそうですが、多少遅くなるのかな?あんまり変わらないのかな?

まとめ

  • Turbolinksはリンク先への遷移を高速にするツール
  • JSが発火しないなどの問題が発生することも
  • loadはturbolinks:loadに変えれば発火する
  • application.jsでコメントアウトすれば簡単に無効化できる