Rails - 如何仅在某些页面上包含Javascript文件

问题描述 投票:5回答:1

我有一个WYSIWYG编辑器,我已在网站中内置并自定义。有许多Javascript文件只需要使用WYSIWYG编辑器加载到页面上;目前它们被加载到每个页面上(甚至在某些页面上打破其他Javascript)。

目前,Javascript文件位于assets/javascript/wysiwyg/中,并不包含在application.js中的require文件中,但由于资产管道(我认为),它仍然包含在每个页面中。

我想知道我是否可以从其他页面中排除这些文件。是否可以将它们从资产管道移动到public/目录并将它们(在咖啡脚本文件中,可能?)导入相应的视图中?

javascript ruby-on-rails ruby ruby-on-rails-4 asset-pipeline
1个回答
17
投票

您可以将要手动加载的任何Javascript文件放在应用程序的public/javascripts/lib目录中,它们不会包含在资产管道中。然后,您可以在需要它们的页面上手动加载它们。

例如,在一个项目中,我使用Chosen jQuery插件,我加载它如下:

<script type="text/javascript" src="/javascripts/lib/chosen.jquery.min.js"></script>

Rails将从public/获取公共文件,因此您只需要从那里引用您的文件(删除public/位)。

这个项目相当庞大,有88个控制器,662个动作,以及总共38个自定义javascript库,它们偶尔会在应用程序中使用,包括降价编辑器,图表库,甚至是jQuery UI。

为了管理蔓延并保持每个页面尽可能紧,我做了两件事:1)在我的控制器中,我设置了一个实例变量@page_libs,列出要加载的库,以及2)布局使用的值@page_libs在需要时包含专业Javascript。

控制器操作可能如下所示:

def edit
  @products = products.find(params[:id])
  @page_libs = [:ui, :textile]
end

并且app/views/layouts/application.html.erb将其包含在正确的位置:

<%- if @page_libs&.include?(:ui) || @page_libs&.include?(:table) %>
    <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js"></script>
    <script type="text/javascript" src="/javascripts/lib/chosen.jquery.min.js"></script>
<% end -%>
<%- if @page_libs&.include?(:swiper) %>
    <script type="text/javascript" src="/javascripts/lib/idangerous.swiper.min.js"></script>
<% end -%>
<%- if @page_libs&.include?(:table) %>
    <script type="text/javascript" src="/javascripts/lib/jquery.handsontable.full.js"></script>
<% end -%>
<%- if @page_libs&.include?(:textile) %>
    <script type="text/javascript" src="/javascripts/lib/textile.js" charset="utf-8"></script>
<% end -%>

请注意,第一个包含jQuery UI,我从CDN加载,而不是从我的应用程序的public加载。此技术与外部库以及您托管的库一样有效。事实上,我的应用程序中的大多数页面仅依赖于2个外部库(jQueryUnderscore.js),但可以选择从外部源加载多达16个其他Javascript库。限制页面上的外部库可以显着减少页面加载时间,这可以直接提升应用程序的性能。

有时,Javascript库也将包含CSS组件。或者,您甚至可以包含特定于页面的CSS。外部样式表可以采用相同的方法。这些是上述Javascript库的相应页面特定样式表“includes”:

<%- if @page_libs&.include?(:ui) %>
    <link rel="stylesheet" type="text/css" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/themes/smoothness/jquery-ui.css">
    <link rel="stylesheet" type="text/css" href="/stylesheets/lib/chosen.min.css">
<% end -%>
<%- if @page_libs&.include?(:swiper) %>
    <link rel="stylesheet" type="text/css" href="/stylesheets/lib/idangerous.swiper.css">
<% end -%>

这样,无论页面需要多少(或几个),我在项目中都有一个点来管理库。我最终可能会在ApplicationController中创建一系列自定义before_action处理程序,以定义页面所需的库。像这样的东西:

before_action: :include_library_ui,     only: [:new, :edit]
before_action: :include_library_swiper, only: [:show]

这将更多地清理控制器操作,并使识别依赖项更容易。但是,考虑到我的代码库的大小和剩下的紧迫任务,我还没有采取这种飞跃。也许它会鼓励你这样做才能开始。

© www.soinside.com 2019 - 2024. All rights reserved.