Whats a better solution for initializing jquery plugins on browser back button that aren't just transforming elements when using turbolinks in Rails 5 like masterslider (photo gallery) or slick (carousel), than reloading the page as I do below?
document.addEventListener 'turbolinks:load', ->
slickElementsPresent = $('.event-card').find('div.slick-slide')[0]
if slickElementsPresent?
window.location.reload();
else
$('.event-card').each ->
$(@).not('.slick-initialized').slick {
infinite: false,
nextArrow: $(@).find('.event-more-details-button'),
prevArrow: $(@).find('.event-card-slide-back-button')
}
To be clear, I check to see on 'turbolinks:load' if there are any html elements that would only be present if the plugin had been initialized, if so, then refresh the page because even though the elements are there, the plugin isn't initialized. And then I initialize the plugin on all the elements that have the class I want it on.
Some people encountered this problem here: https://github.com/turbolinks/turbolinks/issues/106 where someone points out
I just want to add for those having similar issues that making an initialization function idempotent is not necessarily the solution in some circumstances. Having done so with dataTables I am able to avoid duplicate elements. However, the cached versions of the elements on the page related to the plugin no longer function on a browser back click as it seems the plugin is not initialized in a cached page.
Reloading the page if the plugin has already changed the DOM because it's being retrieved from the cache when someone presses the back button just seems pretty bad, but its the best I've come up with so I'm turning to the world for more ideas!
UPDATE:
So some jquery plugins have great 'undo'/'destroy' methods and if that's the case it's better to add an event listener on "turbolinks:before-cache"
and then call that method like so:
document.addEventListener "turbolinks:before-cache", ->
$('.event-card').each ->
$(@).slick('unslick');
but some jquery plugins do not have destroy functions or destroy functions that achieve this. Like masterslider has a $('your-slider-element').masterslider('destroy')
function, but it doesn't 'undo' the javascript magic it applies to your html so much as just getting rid of it entirely, and so when you come back to the page from the browser back or forward button, the slider simply doesn't exist, because the html element it gets triggered on has been destroyed. That means for some plugins, the best answer I still have is to reload the page entirely when the page they are on is navigated to via the browser back and forward buttons.