I am trying to destroy and re-load my Flickity slideshow while using Swup for page transitions, and I am not having much luck. This is my js file:
import Swup from 'swup';
var Flickity = require('flickity');
function init() {
if (document.querySelector('.testimonials-slideshow')) {
var flkty = new Flickity('.testimonials-slideshow', {
wrapAround: true,
pageDots: false,
autoPlay: true,
arrowShape: 'M68.374,83.866L31.902,50L68.374,16.134L64.814,12.3L24.214,50L64.814,87.7L68.374,83.866Z'
});
}
}
function unload() {
flkty.destroy();
}
init();
const swup = new Swup();
swup.on('contentReplaced', init);
swup.on('willReplaceContent', unload);
But when I try this I get the error flkty is not defined
. Can anyone give me any pointers on this?
As mentioned by CBroe, your var
is undefined because of where you define it. It is defined in a function, but should be defined at the "top level".
import Swup from 'swup';
var Flickity = require('flickity');
// Added a "global" definition here:
var flkty;
function init() {
if (document.querySelector('.testimonials-slideshow')) {
// Removed var:
flkty = new Flickity('.testimonials-slideshow', {
wrapAround: true,
pageDots: false,
autoPlay: true,
arrowShape: 'M68.374,83.866L31.902,50L68.374,16.134L64.814,12.3L24.214,50L64.814,87.7L68.374,83.866Z'
});
}
}
function unload() {
flkty.destroy();
}
init();
const swup = new Swup();
swup.on('contentReplaced', init);
swup.on('willReplaceContent', unload);
Furthermore, if you are using any kind of module bundler, sometimes it can still get lost, so you could consider doing something like:
window.flkty = new Flickity('.testimonials-slideshow', ...
And always reference it in that way, i.e.
window.flkty.destroy();
That's it for your variable definition. The next potential error is that you only init flkty
when the query selector matches:
if (document.querySelector('.testimonials-slideshow')) {
But you destroy it every willReplaceContent
, so really you could do with a check on "is it inited, this page load?". In this instance, you can do a check like so:
// Init the var as false:
var flkty = false
function init() {
if (document.querySelector('.testimonials-slideshow')) {
flkty = new Flickity('.testimonials-slideshow', ...);
}
}
function unload() {
if(flkty){
flkty.destroy();
// Make sure the flkty var is set to false at the end:
flkty = false;
}
}
This can all get a bit out of hand, so what we started doing was creating modules. Here is a skeleton of a carousel module we use:
// modules/Carousel.js
import Swiper from "swiper";
export default {
carouselEl: null,
carouselSwiper: null,
setup() {
this.carouselEl = document.getElementById("header-carousel");
if (!this.carouselEl) {
// Just stop if there is no carousel on this page
return;
}
this.carouselSwiper = new Swiper(this.carouselEl, { ... });
this.carouselSwiper.on("slideChange", () => { ... });
},
destroy() {
// If we already have one:
if (this.carouselSwiper) {
this.carouselSwiper.destroy();
}
// Make sure we are reset, ready for next time:
this.carouselSwiper = null;
},
};
Then, in our main.js we do something like you have:
import Carousel from "./modules/Carousel.js";
function init(){
Carousel.setup();
// Add more here as the project grows...
}
function unload(){
Carousel.unload();
}
swup = new Swup();
swup.on("contentReplaced", init);
swup.on("willReplaceContent", unload);
init();
All of the modules have setup
and unload
functions that won't break if the elements don't exist, so we can call all of them on each page load and unload.
I love swup but also have personal experience in the nightmare of initing and destroying things so let me know if you need any further help.