9
7

More than 3 years have passed since last update.

[Rails]リロードしないとJavaScript(jQuery)が動かない問題

Posted at

今回はRails初心者によくありがちな、リロードしないとjQueryが動かない問題について、記事にしていきます。

ぼく自身この問題には何度も直面していまして、対応策をあまり理解せずに、呪文のようにコードにコピペしていました。。
Turbolinksについて調べて理解が深まりましたので、初心者の方にもわかりやすく解説したので、最後まで読んでいただき理解してコードを書いていきましょう!

開発環境

ruby 2.6.3
Rails 5.2.6

何が原因?

まず結論から書いていきます。
リロードしないとjQueryが動かない問題の原因の9割はTurbolinksが関係しています。

たぶん何度か同じ経験をされた方は「またか」となるはずです。
なのでTurbolinksを削除したり、無効にすることで解決します。

対応策

対応策は3パターン。

①Turbolinksを削除する

Turbolinksが原因なら削除すればいいのではという記事もよく見かけますが、この方法はおすすめしません。
あとで解説しますが、Turbolinksはページ遷移時の表示の高速化に一役買ってるのでそのままにしている方が、便利です。

②jsファイルでTurbolinksを無効化する

この方法がおすすめです。
たとえば、.alert_btnをクリックしたら[Hello World!]とアラートを表示する処理があるとします。

assets/javascript/application.js
$(function () {
  $('.alert_btn').click(function(){
    alert('Hello World!')
  });
});

この処理の記述自体は正しいのですが、Turbolinksのせいでリロードしないと発火しません。
なのでTurbolinksを無効化する処理を追加します。

assets/javascript/application.js
// 以下1行を追加
$(document).on('turbolinks:load', function() {
  $(function () {
    $('.alert_btn').click(function(){
      alert('Hello World!')
    });
  });
// 閉じタグも忘れず追加
});

これで、画面遷移後、リロード無しで動作するはずです。

③link_toでTurbolinksを無効化する

②の方法はjsファイルに記述しましたが、link_toに記述する方法もあります。
link_toにdata: {"turbolinks" => false}を追加することで、リンク先のTurbolinksを無効化できます。

<%= link_to 'Top', root_path, data: {"turbolinks" => false} %>

そもそもTurbolinksとは

ここまででTurbolinksは無効化できて動作自体は問題なくできているはずですが、Turbolinksについてはわからないままだと思います。
ぼくも今までは「Turbolinksようわからんけど、②のコード追加したらちゃんとなるしええか」と思っていました。

なのでそもそものTurbolinksに触れていきます。

先程もちらっと触れましたが、Turbolinksは画面遷移を高速化してくれるJavaScriptのライブラリで、RailsではGemによって管理され、デフォルトで入っています。(対応策①の削除するを実行したければGemfileから削除すればいい)

:
gem 'turbolinks', '~> 5'
:

Turbolinksの仕組み

画面遷移を高速化してくれる便利なやつとわかったので、仕組みを確認します。

  • Turbolinksはaタグへのクリックイベントを起点として動作
  • 遷移元のheadタグ内と遷移先のheadタグ内の情報に差分があれば差分を取り込む
  • 遷移元のbodyタグの中身を遷移先のbodyタグの中身へと置き換える
  • 遷移先のページを一から新たに読み込んでいるわけではない

つまり、aタグをクリックしたときに、headタグ内の差分を取り込んで、bodyタグを変更するだけで、一からページのファイルを読み込む必要がないので、表示が高速化されます。

なぜ動かなかったのか

仕組みが分かったので、リロードしないとJavaScript(jQuery)が動かない問題の原因を整理していきます。

Turbolinks発動時、遷移先のページを一から新たに読み込んでいるわけではないので、jsファイルが読み込まれていないという状況が発生し動作しないのです。

つまり、aタグのクリックを使用しない、リロードやURLの直打ちのページ遷移だとTurbolinksは発動しないので、jQueryは問題なく動く。

やっと、根本的な原因が見えてきました。

だから、対応策としてTurbolinksを無効化するのが有効だったわけです。

まとめ

対応策としては3パターン

①Turbolinksを削除する
②jsファイルでTurbolinksを無効化する
③link_toでTurbolinksを無効化する

Turbolinksの仕組み

  • Turbolinksはaタグへのクリックイベントを起点として動作
  • 遷移元のheadタグ内と遷移先のheadタグ内の情報に差分があれば差分を取り込む
  • 遷移元のbodyタグの中身を遷移先のbodyタグの中身へと置き換える
  • 遷移先のページを一から新たに読み込んでいるわけではない

今までなにも考えずに呪文コードを使っていましたが、Turbolinksの仕組みを知ることで、深い理解が得られました。

この記事を読んで、エラーを改善するだけでなくTurbolinksを理解していただければ幸いです。

9
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
7