Rails 5 で Javascript がうまく動かない時の対処法

Rails 5.x で Javascript がうまく動かない時の対処法

ちょっとハマったので、備忘録として残しておきます。

結論を先に言ってしまうと「turbolinks」のおかげでうまく動かなくなっているっぽいです。

turbolinks について

turbolinks は Rails4 の高速化の為に導入された機能で

リンクを踏んだ時にページを普通にロードする代わりにJavaScriptAjaxして何か上手いことしてくれる機能。

でもコイツが動いてるとデフォルトではjQueryが思い通りに動かなくなる事があります。

症状:ページ内リンクのスクロールができない

ruby on railsポートフォリオサイトを作ってみました。

その際に、各項目へスクロールして飛んで欲しいと思いました。

See the Pen Scroll by halneko (@halneko5121) on CodePen.

↑こういうやつ。

ただ最初実装した時は、各項目へ移動はするのですが

瞬間移動的な動きで、ぐいーんとスクロールする感じではありませんでした。

自分の開発環境

環境Cloud9
Rubyruby 2.5.3p105
RailsRails 5.2.3

対処法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「RailsjQueryを使えるようにする」

↑こちらの記事を参考に。

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を使用して機能させる必要がある。
具体的には、jQueryPopper.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 をご利用の方はお気をつけ下さい。

それでは今回はこのへんで👋