QA@IT

Rails 特定ページにのみ適用するJavaScriptの指定方法は?

11126 PV

お世話になります。
Rails(バージョン問わず)にて、
JavaScriptのファイルをcoffeescriptではなく、通常のjsファイルとして作成し、
特定のビューのみで読み込ませる場合、どのように配置し、どのように読みこめばよいのでしょうか?

例えば、ViewとしてProducts/index.html.erbのみでスクリプト(product_index.js)を読み込む場合、
app/assets/javascriptsにおけばアプリケーション全体で読み込まれると思います(3.1以降?)。

product_index.jsをProducts/index.html.erbでのみ、読み込ませる場合(外部ファイルとして)はどのように
html(erb)側で記述すればよいのでしょうか?

コントローラ単位での読み込みでも構いません(layouts/products.html.erbに読み込みを記述する)。

また、一般的にRailsアプリにおいてassetsフォルダに置いたJSはアプリ全体で読み込みがされてしまいますが、
読み込みをするしないを振り分ける設定はどのようにされているのでしょうか?

よろしくお願いいたします。

  • app/assets/javascripts に置いていても、application.js.erbでrequire してるんでもなきゃ、全体で読み込まれることはないのでは?私が何か勘違いしてるんでしょうか。。。 -

回答

コメントにちろっと書きましたが、app/assets/javascripts 配下のJavaScriptファイルがひとつのJSファイルにまとめられるのは、Assets Pipeline のデフォルト動作であって、変更可能です。
application.js.erb の記述を変更すればこの動作も変わります。

//= require jquery  
//= require jquery_ujs  
//= require_tree .  

こんな感じになっていると思いますが、//= require_tree . を削除すると良いです。
あとは、個々の view なりなんなりで使用する JSファイルを javascript_include_tag で読み込めばいいですね。

全部をまとめたくはないけれど、サイト上で概ね共通で利用される JavaScript をまとめて利用したいという場合は、application.js.erb に記述します。
サイトがある程度の規模になると JS ファイルだけでも結構な容量になったりもしますし。

//= require shared/array_index_of
//= require jquery
//= require jquery_ujs
//= require shared/jquery.blockUI
//= require shared/jquery.notifyBar
//= require shared/jquery.ui.core.min
//= require shared/jquery.ui.datepicker
//= require shared/jquery.ui.datepicker-jp
//= require shared/jquery.ui.selectable
//= require shared/jquery.cookie

こんな感じですね。パスは app/assets/javascripts からの相対パスを記述すれば良いです。
*.coffee も *.js も *.js.erb も特に拡張子書かなくても良いです。
記述順にひとつにまとめられるので、順番には気をつける必要があります。

application.js.erb には他に require_directory とか require_self といった記述もあります。
application.css.erb も同様の動作なので、まとめたいものだけまとめると良いです。

こういうサイトを読むと勉強になります。
http://ja.asciicasts.com/episodes/279-understanding-the-asset-pipeline

編集 履歴 (0)
  • 詳しいご説明ありがとうございます。この例はモバイル用のソースですか?規模が大きなソースはまだ読む経験がないので、大きめの規模でのイメージができてよかったです。treeをはずして個別で指定すればよいのですね。参考になります。ありがとうございました。 -
  • application.js.erbでのまとめる対象のJSファイルの記述例なので、モバイルかどうかは関係ありませんよ。 -

asset pipeline 導入後は、逆にスクリプト側で、全ページで読まれることを想定して、特定のページでしか動作しないように作るのがよいのではないかと思っています。bodyのidで分かるようにしておくとかlocationを見るとか。

publicの下などに個別のjavascriptを置いて明示的にそれだけ指定して読ませることも可能ですが、Rails4におけるturbolinksの導入で、HEADの中身をリクエスト毎に評価しないという方向性を打ち出していることには留意したほうがよいでしょう。

編集 履歴 (0)
  • publicに置いて、/javascript.jsのスクリプトタグで出来ました!ありがとうございます。やはり、一括で読み込みを行なってスクリプト側で動作対象のページを指定するのがメンテナンス・パフォーマンス的にもいいんでしょうか。publicに置けば個別に記述できることがわかりました。ありがとうございました。 -
  • turbolinkについて調べました。これは一括で記述する方がよさそうですね。。ありがとうございます。 -

https://github.com/Verba/jquery-readyselector を使っています。昔いっしょのプロジェクトだった凄腕プログラマーの人に教わりました。

編集 履歴 (0)
  • どんぴしゃのgemですね。ありがとうございます。しかし、私のレベルではturbolinkを考えるとおとなしく一括でjavascript書けるところから始めてみます。ありがとうございました。 -
ウォッチ

この質問への回答やコメントをメールでお知らせします。