When you have a html site with turbolinks loaded and the following in the element of each and every page...
<html>
<head>
<!-- load jQuery -->
<script type="text/javascript">
console.log("script in html > head")
</script>
<script type="text/javascript">
$(document).ready(function() {
console.log("script in html > head on document 'ready' event");
});
</script>
<script type="text/javascript">
$(document).on("turbolinks:load", function() {
console.log("script in html > head on document 'turbolinks:load' event");
});
</script>
<!-- load turbolinks -->
</head>
<body> ... </body>
</html>
.. then the console prints ...
script in html > head
script in html > head on document 'ready' event
script in html > head on document 'turbolinks:load' event
... on the first visit and ...
script in html > head on document 'turbolinks:load' event
... on any subsequent visit. Instead of having these script tags within the head tag, we could also have created separate JavaScript files, it would not have made any difference. But this only is true when you put the same JavaScript in the head of each and every page.
So let us make it a little bit more interesting. Let us modify a single page we now call subpage so that it contains the following tags within its body. When we visit this page ...
<html>
<head>...</head>
<body>
<script type="text/javascript">
console.log("script in subpage")
</script>
<script type="text/javascript">
$(document).ready(function() {
console.log("script in subpage on document 'ready' event");
});
</script>
<script type="text/javascript">
$(document).on("turbolinks:load", function() {
console.log("script in subpage on document 'turbolinks:load' event");
});
</script>
</body>
</html>
... then the following is printed ...
script in subpage
script in subpage on document 'ready' event
script in html > head on document 'turbolinks:load' event
script in subpage on document 'turbolinks:load' event
... so all script elements are executed plus the one which has previously been registered. Now, when we visit any other page, the console prints ...
script in html > head on document 'turbolinks:load' event
script in subpage on document 'turbolinks:load' event
... which makes sense as only the two which are registered on the turbolinks:load
event are triggered. But what if we revisit that subpage again? Then we get ...
script in subpage
script in subpage on document 'ready' event
script in subpage
script in subpage on document 'ready' event
script in html > head on document 'turbolinks:load' event
script in subpage on document 'turbolinks:load' event
script in subpage on document 'turbolinks:load' event
script in subpage on document 'turbolinks:load' event
... which is really strange (see turbolinks/turbolinks#167). Removing the obvious two lines which happened on any other page, we see that it basically contains two times the statements which are caused by the script tags of this particular page. No idea right now why this is happening.
If one revisits this special page, we get the same output as before, but the log message script in subpage script in subpage on document 'turbolinks:load' event
is printed always two more times than before.
So how can this be solved?
I recommend to put all code in the head of every page and register it under the turbolinks:load
event.
If one needs to pass data to the executing JavaScript code, I would recommend to use the data attributes of the HTML elements instead.
For instance, do the following:
<div class="myspecialclass" data-important-info="asdf"/>
$(document).on("turbolinks:load", function(event) {
$(".myspecialclass").each(function(index) {
var element = $(this);
// abort if this has already been applied
var done = element.data("done");
if(done === true) {
return;
}
// do the real stuff with the real variables
var data = element.data("important-info");
// do something with this
element.data("done", true); // make sure that if this is fired again we do not call it again
});
});
- Using marquee with turbolinks resets the position of the CSS-based marquee upon changing the page even with
data-turbolinks-permanent
is set.