admin管理员组

文章数量:1391969

I had a lot of trouble to scope my javascript and css files on my rails app. By scoping, I mean :

How to deal with java-script and CSS only used in one page or one controller ?

I tried some solutions but they were all plicated and not so elegant :

  • I saw some advices like this one : including my .js file directly on my .erb file like so :

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

    and then yield that in the application layout. But that means doing one more request to the server in order to get the .js file. I think it is important to stay with only one .js file and one .css file for the application, created by the asset pipeline

  • I saw some other advices like testing if my HTML tag was present on the DOM with the .length method of jquery. That's still mean testing on every page if on particular tag is present (knowing it will be present in only one or two pages).

I found a solution that's is easy to implement and, in my point of view, elegant.

I had a lot of trouble to scope my javascript and css files on my rails app. By scoping, I mean :

How to deal with java-script and CSS only used in one page or one controller ?

I tried some solutions but they were all plicated and not so elegant :

  • I saw some advices like this one : including my .js file directly on my .erb file like so :

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

    and then yield that in the application layout. But that means doing one more request to the server in order to get the .js file. I think it is important to stay with only one .js file and one .css file for the application, created by the asset pipeline

  • I saw some other advices like testing if my HTML tag was present on the DOM with the .length method of jquery. That's still mean testing on every page if on particular tag is present (knowing it will be present in only one or two pages).

I found a solution that's is easy to implement and, in my point of view, elegant.

Share Improve this question asked Jul 13, 2014 at 4:43 user3704659user3704659
Add a ment  | 

2 Answers 2

Reset to default 9

Requirements:

in your application layout change

<body>

to

<body class="#{controller_name}_#{action_name}">

The body will have a different class for every page. For example, on a blogging application with an article_controller and an index action on this controller, the body will be :

<body class='article_index'>

CSS Scoping

The CSS scoping is almost immediate. If you have some styles that only need to be rendered on a certain page (let's say article#index), you just need to ad in you SCSS file :

body.article_index {
# CSS STYLE HERE
}

You don't need to add very long class names everywhere.

Javascript scoping

You need to download jquery-readyselector. This plugin extends .ready() to provide a nice syntax for page-specific script :

$('.article_index').ready(function () {
    alert("I'm on article#index !");
});

An other great things about this plugin is that it is working with turbolink.

Here you can see one of my previous question about turbolink. In order to make my java-script work on page loading AND on page change, someone proposed to me something like that :

// acmodate Turbolinks
$(document).on('ready page:change', function() {
// STUFF
});

But sometime (on the first page loaded), the function was executed twice (one for ready, one for page:change), now I just use jquery-readyselector like so :

// acmodate Turbolinks
$('nav.nav').ready(function() {
// STUFF
});

and the function will be executed once on every scenario.

I hope this will helps someone.

Conditional Layout

If you only want to show css / js assets on a specific page, you'll either be best calling the asset in the view itself (which isn't remended), or just set a condition in your layout to call the files you need:

#app/views/layouts/application.html.erb
<html>
   <head>
      <% if controller_name == "test" && action_name == "index" %>
         ...
      <% end %>
   </head>
</html>

Something which will help you are the controller_name and action_name helpers - they will give you the reference to the controller or action your page has rendered.

--

Turbolinks

In regards to your answer, I don't understand what you're trying to propose. There's a problem here:

$('nav.nav').ready(function() { //-> wrong syntax

If you want to incorporate Turbolinks, you need to use either the event hooks of Turbolinks, or javascript delegation:

var nav_ready = function() {
   // do stuff here
};

$(document).on("page:load ready", nav_ready);

本文标签: jqueryHow to scope efficiently javascript et css on a rails appliacationStack Overflow