Rails 5 で Javascript がうまく動かない時の対処法
Rails 5.x で Javascript がうまく動かない時の対処法
ちょっとハマったので、備忘録として残しておきます。
結論を先に言ってしまうと「turbolinks」のおかげでうまく動かなくなっているっぽいです。
turbolinks について
turbolinks は Rails4 の高速化の為に導入された機能で
リンクを踏んだ時にページを普通にロードする代わりにJavaScriptでAjaxして何か上手いことしてくれる機能。
でもコイツが動いてるとデフォルトではjQueryが思い通りに動かなくなる事があります。
症状:ページ内リンクのスクロールができない
↑ruby on rails でポートフォリオサイトを作ってみました。
その際に、各項目へスクロールして飛んで欲しいと思いました。
See the Pen Scroll by halneko (@halneko5121) on CodePen.
↑こういうやつ。
ただ最初実装した時は、各項目へ移動はするのですが
瞬間移動的な動きで、ぐいーんとスクロールする感じではありませんでした。
自分の開発環境
対処法1「turbolinks」をオフに
↑こちらの記事を参考に。
Rails project 作成時の場合
rails new app_name --skip-turbolinks
Rails project 作成後の場合
Gemfile の turbolinks 行をコメントアウトする。
Gemfile
# Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks
# gem 'turbolinks'
「application.html.erb」から turbolinks を削除する
削除前
application.html.erb
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
削除後
application.html.erb
<%= stylesheet_link_tag "application", media: "all" %>
<%= javascript_include_tag "application" %>
application.js から turbolinks を削除する
app/assets/javascripts/application.js
//= require jquery
//= require jquery_ujs
//= require turbolinks <- 削除
//= require_tree .
bundle install
% bundle install
これで「turbolinks」をオフにできました。
対処法2「RailsでjQueryを使えるようにする」
↑こちらの記事を参考に。
Gemの追加
- Gemfileに「
gem "jquery-rails"
」を追記する。 - 「
bundle update
」を実行。
application.jsに追記
//= require activestorage
//= require turbolinks
//= require jquery <- 追加
//= require jquery_ujs <- 追加
//= require_tree .
※注意
上記の追加する2行は「//= require_tree . 」よりも前に記述するようにしましょう。
「jquery」たちを require してから 「require_tree . 」の順番でないと
「app/assets/javascripts/」以下に配置したスクリプトがうまく動かない可能性があります。
対処法3「Bootstrap」の jQuery 読み込みを外す
自分は「Bootstrap」を利用していたのですが
↑Bootstrap のスタートガイドを見てみると
JS v4.3.1時点
多くのコンポーネントでは、JavaScriptを使用して機能させる必要がある。
具体的には、jQuery、Popper.js、独自のJavaScriptプラグインが必要。
以下の <script>
をページの終わり近くにある </body>
タグの直前に置いて有効にする。
最初にjQueryが来て、Popper.js、それからJavaScriptのプラグインが来なければならない。
以下ではjQueryのスリム版(ajaxとエフェクトモジュールを除外したバージョン)を使用しているが
フルバージョン版もサポートしている。
と記述されており
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM crossorigin="anonymous"></script>
上記のコードを貼り付けるように書かれています。
がしかし
自分はここでハマってしまいました。
ちゃんと調べてないですが「対処法2」で jQuery を利用できるようにしたのに
上記でまた jQuery を読み込んでおり、おかしな事になってしまったのかなと。
試しに動かしてみる
HTML
<a href="#1">#1にジャンプ</a><br/>
<a href="#2">#2にジャンプ</a><br/>
<a href="#3">#3にジャンプ</a><br/>
<br><br>
<br><br>
<br><br>
<p id="1">ジャンプ先1</p>
<br><br>
<br><br>
<br><br>
<p id="2">ジャンプ先2</p>
<br><br>
<br><br>
<br><br>
<p id="3">ジャンプ先
JavaScript
<script>
$(function(){
$('a[href^="#"]').click(function(){
var speed = 1000;
var href= $(this).attr("href");
var target = $(href == "#" || href == "" ? 'html' : href);
$("html, body").animate(
{scrollTop: target.offset().top}, speed, "swing");
return false;
});
});
</script>
どうでしょう、動きましたでしょうか。
めでたしめでたし
お疲れ様でした!
自分は 「「Bootstrap」のjQuery 読み込みを外す」の部分で数時間ハマってました。
Bootstrap をご利用の方はお気をつけ下さい。
それでは今回はこのへんで👋