Reinitialize Slick Carousel after “unslick”

Slick: the last carousel you'll ever need

The popular Slick Carousel jQuery plugin promotes itself as “the last carousel you’ll ever need,” and it is quite a powerful library. Slick Carousel enables us to have responsive, swipe-enabled carousels on Growella that are both easy to use and to implement.

If there’s one major drawback to Slick Carousel, however, it’s that the plugin doesn’t let you easily disable the carousel at a certain breakpoint, then re-enable it if the user resizes his/her screen again. Fortunately, with a little bit of JavaScript, we have a pattern that works.

Why might I need to reinitialize Slick Carousel?

Admittedly, it’s not super-common for average users to constantly resize their browser windows, but one of the main goals in building Growella is to avoid unexpected behaviors for our users (Alen, our Director of User Experience, has made this a priority as we’ve built the site).

An animation of a user constantly resizing a browser viewport
Designers and developers? All the time. Typical users? Rarely.

Let’s say a user is on a tablet, then chooses to rotate the device in order to watch a video. Upon returning to the page and re-orienting the device, we want to make sure that the items that were once in a carousel aren’t suddenly stacked. Give the user the experience that he or she is used to, or the site will feel broken.

Disable Slick Carousel at a certain breakpoint

Slick Carousel makes it very easy to disable (or, in Slick’s terms, “unslick”), at a certain breakpoint: add a breakpoint under the responsive settings node and pass "unslick" instead of an object to the breakpoint’s settings:

$('#my-carousel').slick({
  mobileFirst: true,
  responsive: [
    {
      breakpoint: 768,
      settings: 'unslick'
    }
  ]
});

If the browser viewport is 768px or wider, Slick Carousel will destroy that instance.

Re-initialize Slick Carousel

Now, let’s say we want to re-initialize (“re-slick?”) Slick Carousel if the screen shrinks below 768px again. According to Simon Goellner, one of the collaborators on Slick Carousel, unslick-ing a carousel cannot be undone; in order to re-initialize the carousel, it’s necessary to add an event listener to the window object’s “resize” event and, if the window is sized appropriately, initialize the carousel anew.

Fortunately, Slick Carousel emits a “destroy” event when a carousel is unslicked; we can use this to register our re-initialization callback.

Before we jump into the code, it’s important to recognize that callbacks like “resize” and “scroll” on the window object can be called many, many times; to prevent our script from killing performance, we’re going to debounce our callback. In the script below, this is being handled via the debounce npm package, but please look into relevant implementations for your setup.

// Import the debounce npm package.
let debounce = require('debounce');

$('#my-carousel').on('destroy', function (ev, slick) {
  let carousel = $(this),
    reinit = debounce(function () {
      /*
       * slick.activeBreakpoint will tell us the breakpoint
       * at which the carousel was destroyed.
       */
      if (slick.activeBreakpoint < window.innerWidth) {
        return;
      }

      // Re-initialize with the old settings.
      carousel.slick(slick.options);

      // Remove this event listener.
      window.removeEventListener(reinit);
    }, 500);

    // Assign our debounced callback to window.resize.
    window.addEventListener('resize', reinit);
}).slick({
  mobileFirst: true,
  responsive: [
    {
      breakpoint: 768,
      settings: 'unslick'
    }
  ]
});

By listening to the “destroy” event, we’re able to assign a callback to run once to reinitialize the slider once we return to a smaller screen, then automatically disable itself. This effectively lets us “re-slick” the carousel automatically, using the same settings.

Leave a Reply