##実装した機能
####開発環境
ruby > 2.6.5
rails > 5.2.4.2
####実装したJS
$(document).ready(function(){
$("#menu").on("click", function() {
$(this).next().slideToggle();
});
});
jqueryを使って、なんの変哲もない開閉式ハンバーガーメニューをつけました。
JSのコード自体の良し悪しはおいておいて、動作としては問題ないはずです。
##状況
初期ロード時には問題なく動作する。
ページ遷移、ブラウザバックのときに挙動がおかしい。
クリックで発火はしているが、開閉をループしたり、不安定。
リロードすると通常動作する。
##考察と対策
動いてはいるので、おそらく読み込みのタイミングが間違っている?
→ ready
onload
ajaxStop
など一通り試してみてもダメ。
グーグル先生に相談したら、こんな記述を発見
$(document).on('turbolinks:load', function () {
...
});
turbolinks:load
なにこれ見たことない…
どうやらRails独自の記述らしいです。
##Turbolinksの扱い
こちらの記事を参考にさせていただきました。
turbolinksチートシート
####Turbolinksとは?
- Ajaxによるページ遷移の高速化のためのライブラリ(Gem)
- ユーザ側から見て、通常のページ遷移と同じように表示される/動作する
- Rails4からデフォルトでインストールされている
つまり、この機能が今回のJSに影響してしまっているようです。
####turbolinksをどう扱うか
Gemなので、消してしまえば解消はできますが解決にはならないので
どう扱うべきかリサーチしてみました。
主にこのような扱いがあります。
- <a>タグごとにturbolinksを無効にする
- turbolinks自体を無効化(削除)する
- JSの読み込み時にturbolinksを適応しない、タイミングを変える
##1.<a>タグごとにturbolinksを無効にする
リンク自体に{"turbolinks" => false}
を指定すると
そのリンクはturbolinksが無効になります。
<%= link_to "HOGE", root_path, data: {"turbolinks" => false} %>
<%# => <a data-turbolinks="false" href="/">HOGE</a> %>
これを記述すれば、間違いなくturbolinksを外すことができます。
特定のスクリプトのみ制御する場合は良さそうですが、さすがに全部に記述するのは厳しそうですね…
##2.turbolinks自体を無効化(削除)する
####Gemを削除
この一行を削除
#gem 'turbolinks', '~> 5'
$ bundle update
####application.jsを編集
//= require turbolinks #この行を削除
###application.html.erbを編集
'data-turbolinks-track': 'reload'
を削除します。
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
これで無効化されました。
JSなどを多用するサイトでなければ無効化してしまうのが確実かもしれません。
##3.JSの読み込みにturbolinksを適応しない
ready
onload
などと同じように、
この記述でturbolinksを適応せずにロードできます。
$(document).on('turbolinks:load', function () {
...
});
他にも、turbolinksを適応するタイミングも変更ができます。
詳しく知りたい方はこちらを参照ください。
その他のライフサイクルイベントをとる
スクリプトごとに微調整が効くので、今回はこれが最適解だと思います。
##まとめ
果たして、Turbolinksは優れた機能なのか、おせっかい機能なのか…
今の所どちらとも言えません笑
デフォルトでインストールされているということは、きっとあったほうが良いのだろうと思いますが…
もっと効果的な使用法をご存じの方はぜひコメントを下さい!