There seem to be two approaches to this problem.
- Keep selected items (@ vedant1811 answer)
- Keep body scroll for selected links.
The second approach is the one I was looking for and could not find anywhere, so I will provide my answer to this question.
The solution here is very similar to the solution of the first approach, but perhaps a little easier. The idea is to capture the current scroll position of the body when an element is clicked, and then scroll to that position after the page loads:
Javascript
Turbolinks.scroll = {} $(document).on('click', '[data-turbolinks-scroll=false]', function(e){ Turbolinks.scroll['top'] = $('body').scrollTop(); }) $(document).on('page:load', function() { if (Turbolinks.scroll['top']) { $('body').scrollTop(Turbolinks.scroll['top']); } Turbolinks.scroll = {}; });
Markup
<a href='/' data-turbolinks-scroll='false'>Scroll preserving link</a>
I use the scroll attribute for the Turbolinks object to store my scroll position when I click the [data-turbolinks-scroll=false] link, and then after scrolling the page, I clear this attribute.
Itβs important that you clear the attribute ( Turbolinks.scroll = {} ), otherwise, subsequent clicks on non-anchored links will continue to scroll to the same position.
Note: depending on the specific html and body style, you may need to scroll scroll off from both. An example of how this can be accomplished:
Turbolinks.scroll = {}; $(document).on('click', '[data-turbolinks-scroll=false]', function (e) { Turbolinks.scroll['top'] = { html: $("html").scrollTop(), body: $("body").scrollTop() } }); $(document).on('turbolinks:load', function() { if (Turbolinks.scroll['top']) { $('html').scrollTop(Turbolinks.scroll['top']['html']); $('body').scrollTop(Turbolinks.scroll['top']['body']); } Turbolinks.scroll = {}; });