Search code examples
javascriptjqueryruby-on-railsruby-on-rails-4turbolinks

JavaScript doesn't execute when navigating from page to page


I'm building my first Ruby on Rails application and I tried to create an animated navigation bar. I'm using jQuery and turbolink.

This is my application.js (under /app/assets/javascripts)

$(document).ready(function(){
  $("#nav").hover(function(){
    $("#nav").animate({left:'10px'});
  },
  function(){
    $("#nav").animate({left:'-220px'});
  });
});

And on application.html.erb (under app/views/layouts), I have

<%= javascript_include_tag "application", "data-turbolinks-track" => true %>

and my super navigation bar, which look like this for now (also under app/views/layouts)

<div id='nav'>
  <%= image_tag('arrow.png', size: '20x20', id: "arrow") %>
  <ul>
    <li><%= link_to 'Main page', root_path%></li>
    <li><%= link_to 'Résumé', resume_path %></li>
  </ul>
</div>

When I load my app, the animation works, but when I navigate to an other page of the app, the animation stops working. If I press F5, it's working again

So if I want to use my navigation bar, I have to refresh every page.

Do you know what can I do to fix this?


Solution

  • It's likely a problem caused by Rails Turbolinks.

    Rails 4.0 introduced a feature named Turbolinks to increase the perceived speed of a website. Turbolinks makes an application appear faster by only updating the body and the title of a page when a link is followed. By not reloading the full page, Turbolinks reduces browser rendering time and trips to the server. With Turbolinks, the user follows a link and sees a new page but your JavaScript thinks the page hasn’t changed because a new page has not been loaded. To resolve the issue, you could disable Turbolinks by removing the turbolinks gem from the Gemfile.

    You can also modify your JavaScript. To make sure every page is tracked when Rails Turbolinks is used, add the following JavaScript:

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

    Turbolinks fires a page:change event when a page has been replaced. The code listens for the page:change event and calls JavaScript method. This code will work even on pages that are not visited through Turbolinks (for example, the first page visited).

    I've written a book, Learn Ruby on Rails, that includes a chapter on JavaScript and covers the Turbolinks issue.