在 Rails 3 应用程序中添加特定于页面的 JavaScript 的最佳方法?

IT技术 javascript ruby-on-rails ruby-on-rails-3
2021-01-26 15:43:43

Rails 3 有一些非常酷的不显眼的 JavaScript。

但我想知道最好的方法是为特定页面包含额外的 JavaScript。

例如,我以前可能做过的地方:

<%= f.radio_button :rating, 'positive', :onclick => "$('some_div').show();" %>

我们现在可以用类似的东西让它不显眼

<%= f.radio_button :rating, 'positive' %>

# then in some other file
$('user_rating_positive').click(function() {
  $('some_div').show();
}

所以我想我的问题是在哪里/如何包含该 JavaScript?我不想填满这个application.js文件,因为这个 JavaScript 只适用于这个视图。我应该以某种方式为每个页面包含一个自定义 JavaScript 文件,还是将其粘贴在标题查找的实例变量中?

6个回答

我喜欢做的是将每个视图的 Javascript 包含在一个content_for :head块中,然后yield在您的应用程序布局中包含该块。例如

如果它很短,那么:

<% content_for :head do %>
  <script type="text/javascript">
    $(function() {
      $('user_rating_positve').click(function() {
        $('some_div').show();
      }
    });
  </script>
<% end %>

或者,如果更长,则:

<% content_for :head do %>
  <script type="text/javascript">
    <%= render :partial => "my_view_javascript"
  </script>
<% end %>

然后,在您的布局文件中

<head>
  ...
  <%= yield :head %>
</head>
@AJP 它更混乱,但它的 http 请求比您的回答少一个。
2021-03-14 15:43:43
为什么不使用<%= javascript_include_tag "my_javascipt_file" %>
2021-03-19 15:43:43
@AJP 我猜那么它就违背了资产管道的目的
2021-03-19 15:43:43
2021-03-25 15:43:43
@luralala 但答案中的代码不是这样做的,而是以一种更混乱的方式?
2021-04-06 15:43:43

如果您只想在一个页面上包含 javascript,当然可以将其包含在页面内联中,但是如果您想对 javascript 进行分组并利用资产管道、缩小的 js 等,则可以这样做并有额外的通过将您的 js 分成仅适用于站点的某些控制器/视图/部分的组来组合并仅加载到特定页面上的 js 资产。

将资产中的 js 移动到文件夹中,每个文件夹都有一个单独的清单文件,因此如果您有一个仅在后端使用的管理 js 库,您可以这样做:

  • 资产
    • javascripts
      • 行政
        • ....js
      • admin.js(管理员组的清单)
      • application.js(应用程序全局组的清单)
      • 全球的
        • ....js

在现有的 application.js 中

//= require jquery
//= require jquery_ujs
//= require_tree ./global // requires all js files in global folder

在新的 admin.js 清单文件中

//= require_tree ./admin // requires all js files in admin folder

通过编辑 config/production.rb 确保加载了这个新的 js 清单

config.assets.precompile += %w( admin.js )

然后调整您的页面布局,以便您可以为页面头部包含一些额外的 js:

<%= content_for :header %>   

然后在您想要包含此特定 js 组(以及普通应用程序组)和/或任何特定于页面的 js、css 等的视图中:

<% content_for :header do %>
  <%= javascript_include_tag 'admin' %>  
<% end %>

你当然可以用 css 做同样的事情,并以类似的方式将它分组,以仅应用于网站的某些区域。

不知道您可以这样做 - 所以您可以拥有一个包含您的清单以及各个 js 组的“清单”文件夹?我可能会试试这个。我确实希望他们在默认情况下有一个稍微理智的设置,因为他们似乎认为您只需将所有 js 都放到一个随处导入的大文件中。
2021-03-15 15:43:43
奇怪的是,如果我使用 ,我会收到 Sprockets::FileNotFound 错误//= require_tree ./global,但如果我使用//= require_directory ./globalRails 3.2.12则不会
2021-03-15 15:43:43
看起来您最终会得到许多脚本标签。我认为资产管道的目标是只有一个脚本标签?我只会编写 javascripts,以便它们是特定于页面的。
2021-03-18 15:43:43
如果您将所有清单保存在同一个位置,您可以告诉 rails 预编译该文件夹中的所有内容。这样你只需要编辑一次 production.rb 并且不需要跟踪你添加的内容。
2021-03-19 15:43:43
我觉得我明白了。不过,避免额外的脚本标签对于页面加载时间非常重要。
2021-04-05 15:43:43

这些答案对我帮助很大!如果有人想要多一点...

  1. 如果您希望它们预编译,您需要将 javascripts 放入清单中。但是,如果您需要每个 javascript 文件,application.js.coffee那么每次导航到不同页面时都会加载所有 javacsript,并且执行特定于页面的 javascript 的目的将落空。

因此,您需要创建自己的清单文件(例如speciifc.js),它将需要所有特定于页面的 javascript 文件。另外,修改require_treeapplication.js

应用程序/资产/javascripts/application.js

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

应用程序/资产/javascripts/specific.js

//= require_tree ./specific

然后在您environments/production.rb使用 config 选项将此清单添加到预编译列表中,

config.assets.precompile += %w( specific.js )

完毕!所有应该始终加载共享javascripts 将放在app/assets/javascripts/global文件夹中,而页面特定的 javascripts 放在app/assets/javascripts/specific. 您可以简单地从视图中调用特定于页面的 javascripts

<%= javascript_include_tag "specific/whatever.js" %> //.js 是可选的。

这已经足够了,但我也想利用它javascript_include_tag params[:controller]当您创建控制器时,会app/assets/javascripts像其他人提到的那样生成关联的 coffeescript 文件有真正的控制器特定的javascripts,只有当用户到达特定的控制器视图时才会加载它们。

所以我创建了另一个清单 controller-specific.js

app/assets/javascripts/controller-specific.js

//= require_directory .

这将包括与控制器关联的所有自动生成的咖啡脚本。此外,您需要将其添加到预编译列表中。

config.assets.precompile += %w( specific.js controller-specific.js )

@AlexChaffee 只有自动可用的文件是application.cssapplication.js其他必须包含在其他文件中,或使用config.assets.precompile. 在这里阅读更多
2021-03-13 15:43:43
另外,我应该把这条线<%= javascript_include_tag "specific/whatever.js" %>放在一个content_for :header块中吗?
2021-03-17 15:43:43
非常感谢详细的回答。我应该把这条线放在哪里 javascript_include_tag params[:controller]目前我的 application.html.erb 有这一行javascript_include_tag 'application'我应该用另一行替换它吗?
2021-03-24 15:43:43
对我来说很奇怪你需要弄乱config.assets.precompile. 不是所有的东西都是app/assets/javascripts/*.js自动预编译的吗?
2021-04-05 15:43:43
清单声明已被移动。我正在运行 Rails 4.2.0。并在 production.rb 文件中找到此注释:#config.assets.precompileconfig.assets.version已移至 config/initializers/assets.rb
2021-04-10 15:43:43

我更喜欢以下...

在您的 application_helper.rb 文件中

def include_javascript (file)
    s = " <script type=\"text/javascript\">" + render(:file => file) + "</script>"
    content_for(:head, raw(s))
end

然后在您的特定视图中(在本例中为 app/views/books/index.html.erb)

<% include_javascript 'books/index.js' %>

......似乎对我有用。

如果您不想使用资产管道或复杂的变通方法来获得必要的页面特定的 javascript(我很同情),最简单和最健壮的方法,它与上面的答案相同,但代码更少,只是为了利用:

<%= javascript_include_tag "my_javascipt_file" %>

注意:与使用的答案相比,这确实需要每个包含标签多一个 http 请求 content_for :head

@Linus 是的,//= require .会将该脚本带入您网站上的任何页面,因此您必须执行类似 Kenny Grant(使用//= require_tree ./global)或 bjg 建议的操作。
2021-03-17 15:43:43
这是迄今为止最简单的方法对我来说,我改变了//= require_tree .//= require_directory .在application.js中,然后创建资产\ JavaScript的一个子目录。请注意,您必须在 config\initializers\assets.rb 中包含新目录以通过添加以下行来预编译您的 js:Rails.application.config.assets.precompile += %w( new_dir/js_file.js )
2021-04-01 15:43:43
javascript_include_tag 正是我正在寻找的,欢呼 AJP
2021-04-05 15:43:43
你把“my_javascipt_file”放在哪里?在资产/javascripts 中?但如果是这样,它不会//= require .在 application.js 中自动获取吗?
2021-04-07 15:43:43