最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

jquery - How to scope efficiently javascript et css on a rails appliacation? - Stack Overflow

programmeradmin0浏览0评论

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);
发布评论

评论列表(0)

  1. 暂无评论