C. Short
C. Short

Reputation: 109

Turbolinks breaks jQuery that is used on multiple pages

I've looked into fixes, most of them say to use the following:

var ready;
ready = function() {

// code here

};

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

The problem is that on every page I have a html5 video, I use jQuery to enable click playing/pausing with the following code:

$('#support-vid').click(function() {
    $(this).get(0).paused ? $(this).get(0).play() : $(this).get(0).pause();
});

What happens however is that on the first page the video works properly, the jQuery is executed as it should be. Though when I go to another page, it just doesn't work. I have to hard refresh to get it to function as it should.

What is the best way to manage this?

Upvotes: 1

Views: 912

Answers (2)

greenif
greenif

Reputation: 1093

var ready = function() {
// code here
};

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

$(document).on('click', '#support-vid', function() {
    var my_element = $(this).get(0);
    my_element.paused ? my_element.play() : my_element.pause();
});

The problem is that when you bind event handler like this

$('#support-vid').click(function()

you bind this handler to certain element. When turbolinks reload the page it replace the whole body and as a consequence replace your element with absolutely new element with the same attributes, in this case ID. And your event handler will never fire again.

There are two approaches to solve this issue: The first one called 'Event delegation', when your bind event handler to document which never replaced and use filters like in the code above. The second approach is rebind event handler on each page ready event and turbolinks page:load event like this:

var ready = function() {
    // code here
    $('#support-vid').click(function() {
        $(this).get(0).paused ? $(this).get(0).play() : $(this).get(0).pause();
    });
};

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

Upvotes: 0

Ruby Racer
Ruby Racer

Reputation: 5740

This answer could have a javascript/jQuery solution...

However, the problem lies in Turbolinks...

There are two ways to go in such scenarios:

1: Don't track the javascript code that defines your desired behaviour... So, somewhere in your layout, within the <body></body> section of your document, maybe after the <%= yield %> part, you could do the following:

<script type="text/javascript" data-turbolinks-eval=true>
    $(function() {
        $('#support-vid').on('click',function() {
            $(this).get(0).paused ? $(this).get(0).play() : $(this).get(0).pause();
        });
    });
</script>

This way, the script tag will be forced to be evaluated on every page load... data-turbolinks-eval=true is default behaviour for scripts with implicitly type set to "text/javascript", so you don't really need to write it... You do however need to write type="text/javascript".

2nd way, is to disable turbolinks on views that cause problems, but I wouldn't go with that.

Upvotes: 1

Related Questions