Embla-carousel: Initialize embla after certain width, and destroy below certain width

Created on 27 Nov 2019  路  11Comments  路  Source: davidcetinkaya/embla-carousel

Hello, i have a problem with initializing Embla carousel after 992px and destroying it below that value.

My js code:

const initBrandsEmbla = () => {
  const brandsEmbla = document.querySelector('.embla__brands');

  if (brandsEmbla !== null) {
    const settings = {
      draggable: false,
      loop: true,
      align: 'start',
      startIndex: 1,
    };

    const embla = EmblaCarousel(brandsEmbla, settings);
    const autoPlayer = autoPlay(embla, 1000);

    const checkEmbla = () => {
      if (window.matchMedia('(max-width: 992px)').matches) {
        // I want to reinitialize it here
        // something like embla.recover() would be helpful
        autoPlayer.play();
      } else {
        embla.destroy();
      }
    }

    checkEmbla();

    // On embla resize, check the width and initialize carousel, or destroy it
    embla.on('resize', () => {
      checkEmbla();
    });
  }
}

window.addEventListener('load', () => {
  initBrandsEmbla();
});

The problem is: it works when i load the window that has width lower than 992, it also works as intended (the carousel stops) when i resize that window above 992px, but when i go back below 992px, the carousel doesn't recover or reinitialize no matter what i do.
I tried many things, but nothing worked so far.

When i try something like that:

const initBrandsEmbla = () => {
  const brandsEmbla = document.querySelector('.embla__brands');

  if (brandsEmbla !== null) {
    const settings = {
      draggable: false,
      loop: true,
      align: 'start',
      startIndex: 1,
    };

    let embla;
    let autoPlayer;

    const checkEmbla = () => {
      if (window.matchMedia('(max-width: 992px)').matches) {
        // I want to reinitialize it here
        embla = EmblaCarousel(brandsEmbla, settings);
        autoPlayer = autoPlay(embla, 1000).play();
      } else {
        embla.destroy();
      }
    }

    checkEmbla();

    // On embla resize, check the width and initialize carousel, or destroy it
    window.addEventListener('resize', () => {
      checkEmbla();
    });
  }
}

window.addEventListener('load', () => {
  initBrandsEmbla();
});

Then it doesn't stop on the desktop, i've ran out of ideas :/

Do you know the solution by any chance?

demonstration resolved

All 11 comments

Hi Jakub (@jakubreron),

Thank you for your question. What happens if you try the following:

const initBrandsEmbla = () => {
  const brandsEmbla = document.querySelector(".embla__brands");

  if (brandsEmbla !== null) {
    const settings = {
      draggable: false,
      loop: true,
      align: "start",
      startIndex: 1
    };

    let embla = null;
    let autoPlayer = null;

    const checkEmbla = () => {
      // Checking the window.innerWidth should suffice
      // We're checking if window width is above or equal to 992 px
      if (window.innerWidth >= 992) {
        // Check to not init Embla when it's already initialized
        if (embla === null) {
          embla = EmblaCarousel(brandsEmbla, settings);
          autoPlayer = autoPlay(embla, 1000).play();
        }
      } else {
        // Check to not destroy Embla when it's not initialized
        if (embla !== null) {
          embla.destroy();
          embla = null;
          autoPlayer = null;
        }
      }
    };

    checkEmbla();

    // On embla resize, check the width and initialize carousel, or destroy it
    window.addEventListener("resize", checkEmbla);
  }
};

window.addEventListener("load", initBrandsEmbla);

I'd very much appreciate feedback if this solves your issue or not. Thank you in advance.

Kindly,
David

Thanks for the reply, when i use the code above, then it's not playing on desktop (which is good), when i resize into mobile, it starts playing, but when i resize into desktop again, then it doesn't stop :/

I only changed "window.innerWidth >= 992" to "window.innerWidth <= 992" because i want the carousel to be initialized on mobile, destroyed on the desktop when i resize into above 992px width, and reinitialized on mobile when i again resize below 992px.

Hello again Jakub (@jakubreron),

I think the check should be window.innerWidth < 992 and not window.innerWidth <= 992. Because I think you want the carousel to be destroyed on 992px and above right?

Kindly,
David

Changed, still doesn't stop / doesn't get destroyed when i resize window to more than 992px :/

@jakubreron would you mind creating a CodeSandbox and sending me the link here? I thinks it's easier to troubleshoot with a sandbox.

Best,
David

I will try to create the sandbox and send it today :D Thanks for the replies and all the help! :D

@jakubreron not a problem. I'm glad if I can help you solve this 馃憤.

Here you go: https://codesandbox.io/s/zealous-black-jsg3j?fontsize=14&hidenavigation=1&theme=dark

Right now, my desired effect is visible only after refreshing, you can see that when you are on desktop resolution and the page is refreshed, the slides are staying still, and are distributed with justify-content: space-between, i want it to stay like that on desktop but when i resize into mobile, then the carousel should start sliding.

So, to summarize :D
On resize:
Desktop -> no carousel
Mobile -> carousel

Thanks!

Hi Jakub (@jakubreron),

Thank you for the CodeSandbox! The reason why the carousel wasn't destroyed is because autoPlayer wasn't correctly stored in a variable and stopped before destroying the Embla instance. I've added the following and it now works as intended:

if (window.innerWidth < 992) {
  if (embla === null) {
    embla = EmblaCarousel(brandsEmbla, settings);
    autoPlayer = autoPlay(embla, 1000); // Store autoPlayer in a variable
    autoPlayer.play();
  }
} else {
  if (embla !== null) {
    autoPlayer.stop(); // stop autoPlayer before destroying Embla
    embla.destroy();
    embla = null;
    autoPlayer = null;
  }
}

馃憠 Here's a working example. I hope this helps.

Kindly,
David

Thank You so much! You are a hero! :muscle: I will recommend Embla carousel to everyone in my company! :grinning:

@jakubreron I'm glad I could help! Thank you, it's very nice of you to recommend Embla Carousel, I really appreciate that 馃槉.

Was this page helpful?
0 / 5 - 0 ratings