Ruby on Rails application. Javascript works fine when you go directly to a page, but if you navigate inside the application from page to page (for example, by the link in the menu), the page itself is drawn normally, but javascript does not work. What could be the problem?

Script (from template):

;(function () { 'use strict'; // iPad and iPod detection var isiPad = function(){ return (navigator.platform.indexOf("iPad") != -1); }; var isiPhone = function(){ return ( (navigator.platform.indexOf("iPhone") != -1) || (navigator.platform.indexOf("iPod") != -1) ); }; // Parallax var parallax = function() { $(window).stellar(); }; // Burger Menu var burgerMenu = function() { $('body').on('click', '.js-fh5co-nav-toggle', function(event){ event.preventDefault(); if ( $('#navbar').is(':visible') ) { $(this).removeClass('active'); } else { $(this).addClass('active'); } }); }; var goToTop = function() { $('.js-gotop').on('click', function(event){ event.preventDefault(); $('html, body').animate({ scrollTop: $('html').offset().top }, 500); return false; }); }; // Page Nav var clickMenu = function() { $('#navbar a:not([class="external"])').click(function(event){ var section = $(this).data('nav-section'), navbar = $('#navbar'); if ( $('[data-section="' + section + '"]').length ) { $('html, body').animate({ scrollTop: $('[data-section="' + section + '"]').offset().top }, 500); } if ( navbar.is(':visible')) { navbar.removeClass('in'); navbar.attr('aria-expanded', 'false'); $('.js-fh5co-nav-toggle').removeClass('active'); } event.preventDefault(); return false; }); }; // Reflect scrolling in navigation var navActive = function(section) { var $el = $('#navbar > ul'); $el.find('li').removeClass('active'); $el.each(function(){ $(this).find('a[data-nav-section="'+section+'"]').closest('li').addClass('active'); }); }; var navigationSection = function() { var $section = $('section[data-section]'); $section.waypoint(function(direction) { if (direction === 'down') { navActive($(this.element).data('section')); } }, { offset: '150px' }); $section.waypoint(function(direction) { if (direction === 'up') { navActive($(this.element).data('section')); } }, { offset: function() { return -$(this.element).height() + 155; } }); }; // Window Scroll var windowScroll = function() { var lastScrollTop = 0; $(window).scroll(function(event){ var header = $('#fh5co-header'), scrlTop = $(this).scrollTop(); if ( scrlTop > 500 && scrlTop <= 2000 ) { header.addClass('navbar-fixed-top fh5co-animated slideInDown'); } else if ( scrlTop <= 500) { if ( header.hasClass('navbar-fixed-top') ) { header.addClass('navbar-fixed-top fh5co-animated slideOutUp'); setTimeout(function(){ header.removeClass('navbar-fixed-top fh5co-animated slideInDown slideOutUp'); }, 100 ); } } }); }; // Animations // Home var homeAnimate = function() { if ( $('#fh5co-home').length > 0 ) { $('#fh5co-home').waypoint( function( direction ) { if( direction === 'down' && !$(this.element).hasClass('animated') ) { setTimeout(function() { $('#fh5co-home .to-animate').each(function( k ) { var el = $(this); setTimeout ( function () { el.addClass('fadeInUp animated'); }, k * 200, 'easeInOutExpo' ); }); }, 200); $(this.element).addClass('animated'); } } , { offset: '80%' } ); } }; var customersAnimate = function() { if ( $('#fh5co-customers').length > 0 ) { $('#fh5co-customers').waypoint( function( direction ) { if( direction === 'down' && !$(this.element).hasClass('animated') ) { setTimeout(function() { $('#fh5co-customers .to-animate').each(function( k ) { var el = $(this); setTimeout ( function () { el.addClass('fadeInUp animated'); }, k * 200, 'easeInOutExpo' ); }); }, 200); $(this.element).addClass('animated'); } } , { offset: '80%' } ); } }; var introAnimate = function() { if ( $('#fh5co-intro').length > 0 ) { $('#fh5co-intro').waypoint( function( direction ) { if( direction === 'down' && !$(this.element).hasClass('animated') ) { setTimeout(function() { $('#fh5co-intro .to-animate').each(function( k ) { var el = $(this); setTimeout ( function () { el.addClass('fadeInRight animated'); }, k * 200, 'easeInOutExpo' ); }); }, 1000); $(this.element).addClass('animated'); } } , { offset: '80%' } ); } }; var workAnimate = function() { if ( $('#fh5co-work').length > 0 ) { $('#fh5co-work').waypoint( function( direction ) { if( direction === 'down' && !$(this.element).hasClass('animated') ) { setTimeout(function() { $('#fh5co-work .to-animate').each(function( k ) { var el = $(this); setTimeout ( function () { el.addClass('fadeInUp animated'); }, k * 200, 'easeInOutExpo' ); }); }, 200); $(this.element).addClass('animated'); } } , { offset: '80%' } ); } }; var testimonialAnimate = function() { var testimonial = $('#fh5co-testimonials'); if ( testimonial.length > 0 ) { testimonial.waypoint( function( direction ) { if( direction === 'down' && !$(this.element).hasClass('animated') ) { var sec = testimonial.find('.to-animate').length, sec = parseInt((sec * 200) - 400); setTimeout(function() { testimonial.find('.to-animate').each(function( k ) { var el = $(this); setTimeout ( function () { el.addClass('fadeInUp animated'); }, k * 200, 'easeInOutExpo' ); }); }, 200); setTimeout(function() { testimonial.find('.to-animate-2').each(function( k ) { var el = $(this); setTimeout ( function () { el.addClass('fadeInDown animated'); }, k * 200, 'easeInOutExpo' ); }); }, sec); $(this.element).addClass('animated'); } } , { offset: '80%' } ); } }; var servicesAnimate = function() { var services = $('#fh5co-services'); if ( services.length > 0 ) { services.waypoint( function( direction ) { if( direction === 'down' && !$(this.element).hasClass('animated') ) { var sec = services.find('.to-animate').length, sec = parseInt((sec * 200) + 400); setTimeout(function() { services.find('.to-animate').each(function( k ) { var el = $(this); setTimeout ( function () { el.addClass('fadeInUp animated'); }, k * 200, 'easeInOutExpo' ); }); }, 200); setTimeout(function() { services.find('.to-animate-2').each(function( k ) { var el = $(this); setTimeout ( function () { el.addClass('bounceIn animated'); }, k * 200, 'easeInOutExpo' ); }); }, sec); $(this.element).addClass('animated'); } } , { offset: '80%' } ); } }; var aboutAnimate = function() { var about = $('#fh5co-about'); if ( about.length > 0 ) { about.waypoint( function( direction ) { if( direction === 'down' && !$(this.element).hasClass('animated') ) { setTimeout(function() { about.find('.to-animate').each(function( k ) { var el = $(this); setTimeout ( function () { el.addClass('fadeInUp animated'); }, k * 200, 'easeInOutExpo' ); }); }, 200); $(this.element).addClass('animated'); } } , { offset: '80%' } ); } }; var countersAnimate = function() { var counters = $('#fh5co-counters'); if ( counters.length > 0 ) { counters.waypoint( function( direction ) { if( direction === 'down' && !$(this.element).hasClass('animated') ) { var sec = counters.find('.to-animate').length, sec = parseInt((sec * 200) + 400); setTimeout(function() { counters.find('.to-animate').each(function( k ) { var el = $(this); setTimeout ( function () { el.addClass('fadeInUp animated'); }, k * 200, 'easeInOutExpo' ); }); }, 200); setTimeout(function() { counters.find('.js-counter').countTo({ formatter: function (value, options) { return value.toFixed(options.decimals); }, }); }, 400); setTimeout(function() { counters.find('.to-animate-2').each(function( k ) { var el = $(this); setTimeout ( function () { el.addClass('bounceIn animated'); }, k * 200, 'easeInOutExpo' ); }); }, sec); $(this.element).addClass('animated'); } } , { offset: '80%' } ); } }; var contactAnimate = function() { var contact = $('#fh5co-contact'); if ( contact.length > 0 ) { contact.waypoint( function( direction ) { if( direction === 'down' && !$(this.element).hasClass('animated') ) { setTimeout(function() { contact.find('.to-animate').each(function( k ) { var el = $(this); setTimeout ( function () { el.addClass('fadeInUp animated'); }, k * 200, 'easeInOutExpo' ); }); }, 200); $(this.element).addClass('animated'); } } , { offset: '80%' } ); } }; // Document on load. $(function(){ parallax(); burgerMenu(); clickMenu(); windowScroll(); navigationSection(); goToTop(); // Animations homeAnimate(); customersAnimate(); introAnimate(); workAnimate(); testimonialAnimate(); servicesAnimate(); aboutAnimate(); countersAnimate(); contactAnimate(); }); }()); 

Connected with javascript_include_tag

  • 2
    In Turbolinks, most likely. - D-side

1 answer 1

In the Rails 5 project, the turbolinks haem is enabled by default. Details about it can be found in the official repository .

Usually clicking on links leads to a full page reload in the browser. We see a white screen on which a new page is gradually loading. The turbolinks heme changes this process - it receives a new AJAX-ovo page, via js, and, having received it, replaces the contents of <body> on the current page. And as a user, you have the feeling of instantly moving to another page, as if you are sitting in a web application on Angular / Ember / React (SPA).

And because of this behavior, your scripts may not work. Previously, each transition led to a full load of the new page, with all the scripts, and their execution. Now, with turbolinks , scripts and styles (and all the contents of <head> ) are loaded only once - when you first open the site. And the scripts of this type are executed ..

 ;(function () { ... }()); 

..only this time.

But turbolinks solves this problem. When navigating to pages, this gem generates js-events to which script launch can be associated. For example:

 $(document).bind('turbolinks:load', function() { ... }); 

Just wrap your scripts in such a construction, and they will be executed every time a new page is loaded - via turbolinks or not.

  • Thanks, sort of worked. Now 2/3 of cases opens the pages normally and 1/3 starts showing js, and then the content of the page disappears, but there’s more like a cant in js itself. - lif3ar