環境:
Ruby 2.7.3
Rails 6.1.4.4
問題
jQueryを使って、例えば「ボタンをクリックしたらモーダルウィンドウが表示される」といったアクションを実装したとする。すると、最初にページに訪れたときは正常に動くのに、ページ遷移を挟んだら動かなくなり、ページをリロードするとまた動き出す...といった不具合が発生する。
サンプルはこんな形↓(「open」というIDを持つオブジェクトをクリックすると、モーダルウィンドウが表示されるような処理)
$(function () {
$("#open").click(function(){
-----処理------
});
});
原因
Turbolinksがjsの読み込みを邪魔している。
まず、
$(function() {});
1行目のこれはコードの省略形で、正確に書くと以下のようになる。
$(document).ready(function {
//処理
});
これが意味するのは、「ページが読み込まれたら、以下のファンクションを起動します」というもので、謂わばトリガー条件を書いていることになる。ただ、ここでTurbolinksの仕様と競合してしまう。
Turbolinksでは、ページを遷移する際にすべてを再度読み込むのではなく、headやbodyの中身だけをリロードすることによって処理の高速化を実現している(詳しくいえばもっと工程があるが割愛する)。そのため、Turbolinksで遷移したときはJSが読み込まれない問題が発生する。
解決方法
1)jQueryを丁寧に記述する
$(document).ready(function {
//処理
});
これが諸悪の根源なので、
$(document).on('turbolinks:load', function(){
//処理
});
と、「Turbolinksでロードが入ったときに発火させる」と丁寧に書いてあげれば解決。
2)Turbolinksを切る
そもそもTurbolinksがなければ問題は起きないので、application.jsでturbolinksを無効化しておく(強硬手段ではある)
// 変更前
//= require turbolinks
// 変更後
// require turbolinks
参考記事