[rails]bodyにclassを付けて特定のページでのみjsが動作するようにする


Asset Pipelineを使用するとjsやcssを結合してくれます。

結合によって高速化できますが、app/assets/javascripts以下のjsが一括で読み込まれてしまうため、js側でページによって機能を切り替える必要があります。

例えばsample-a.jsで

$(function() {
  $('p').css('color', 'red');
});

と書いてsample-b.jsで

$(function() {
  $('p').css('color', 'blue');
});

と書いた場合、全ページのp要素の色がblueになってしまいます。
(sample-b.jsがあとで読み込まれてsample-a.jsのcss変更を上書き)

そこで、jquery-readyselector を使ってみます。

jquery.readyselector.jsをダウンロードし、vendor/assets/javascripts以下に設置します。

application.jsにrequire jquery.readyselectorを追加。

# app/assets/javascripts/application.js

//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require jquery.readyselector
//= require_tree .-

layouts/application.html.erbのbodyタグのclassにコントローラ名とアクション名をつけるように変更。

 
# app/views/layouts/application.html.erb

<body class="<%= controller_name -%> <%= action_name -%>">

これで各ページ用のjsに$(‘.コントローラ名.アクション名’).readyを記述すればページごとに機能を切り替えることができます。

# app/assets/javascripts/home.js.coffee

# js
$('.home.index').ready(function () {
  console.log('home#index');
});

# coffee
$('.home.index').ready ->
  console.log 'home#index'

参考