Search code examples
javascriptjquerysliderslick.js

Hide Active Slide in `asNavFor` slider in Slick Slider


Question

Is there a way to hide the currently-active slide from a slider in Slick Slider?

Motivation

I am building a Featured Posts slider. One post will be featured prominently, while the remaining posts will feature as previews in a column on the side. A total of 5 posts will be shown at a time.

This is pretty easy to do with Slick Slider (1.9.0) but it has one issue: the "remaining posts" section should only show the remaining posts and not the current post. So when a post is selected it should scroll out of view in the slider, and the featured post slider will change to use the slide at the same index.

Description of the Action

Basically, the initial state should be:

Featured Slider: Slide 1 is visible, all others are hidden. Remaining Slider: Slide 1 is hidden, Slides 2-5 are visible.

If I click on slide 2 from the Remaining Slider:

Featured Slider: Slide 2 is visible, all others are hidden. Remaining Slider: Slide 2 slides out of view, Slide 3 becomes the new top post followed by (in order) 4, 5, 1.

JS Fiddle

Here's the JS Fiddle I'm working on: https://jsfiddle.net/zak_rhm/Lks61ah7/71/

HTML

<div id="Large_Slider">
    <!-- Should only show one slide at a time. -->
    <article class="slide">
        <h2>Slide 1</h2>
    </article>
    <article class="slide">
        <h2>Slide 2</h2>
    </article>
    <article class="slide">
        <h2>Slide 3</h2>
    </article>
    <article class="slide">
        <h2>Slide 4</h2>
    </article>
    <article class="slide">
        <h2>Slide 5</h2>
    </article>
</div>
<ul id="Small_Slider">
    <!-- Should only show four slides at a time, never show the slide in #Large_Slider -->
    <li id="slide">Slide 1</li>
    <li id="slide">Slide 2</li>
    <li id="slide">Slide 3</li>
    <li id="slide">Slide 4</li>
    <li id="slide">Slide 5</li>
</ul>

JavaScript (jQuery)

var $slider_lg = $("#Large_Slider")
var $slider_sm = $("#Small_Slider")

$slider_lg.slick({
  slidesToShow: 1,
  slidesToScroll: 1,
  asNavFor: '#Small_Slider',
  dots: true,
  fade: true
});

$slider_sm.slick({
  arrows: false,
  slidesToShow: 4,
  slidesToScroll: 1,
  asNavFor: '#Large_Slider',
  focusOnSelect: true,
  vertical: true,
  verticalSwiping: true
});

Solution

  • This should do what you're looking for: https://jsfiddle.net/kmsv5xn8/

    I changed your HTML so that the "Small_Slider" section begins at #2 and each slide has a data-sm-slide attribute:

    <ul id="Small_Slider" class="slick-slider">
      <li id="sm-slide-2" class="slide slide--sm" data-sm-slide="2">
        <img src="https://via.placeholder.com/640x480.png/0f9/333?text=Slide+2" alt="Slide 2" height="48" width="64" class="slide--sm__img" />
        <span class="slide--sm__title">Slide 2</span>
      </li>
      <li id="sm-slide-3" class="slide slide--sm" data-sm-slide="3">
        <img src="https://via.placeholder.com/640x480.png/f09/fff?text=Slide+3" alt="Slide 3" height="48" width="64" class="slide--sm__img" />
        <span class="slide--sm__title">Slide 3</span>
      </li>
      <li id="sm-slide-4" class="slide slide--sm" data-sm-slide="4">
        <img src="https://via.placeholder.com/640x480.png/f90/333?text=Slide+4" alt="Slide 4" height="48" width="64" class="slide--sm__img" />
        <span class="slide--sm__title">Slide 4</span>
      </li>
      <li id="sm-slide-5" class="slide slide--sm" data-sm-slide="5">
        <img src="https://via.placeholder.com/640x480.png/90f/fff?text=Slide+5" alt="Slide 5" height="48" width="64" class="slide--sm__img" />
        <span class="slide--sm__title">Slide 5</span>
      </li>
      <li id="sm-slide-1" class="slide slide--sm" data-sm-slide="1">
        <img src="https://via.placeholder.com/640x480.png/09f/333?text=Slide+1" alt="Slide 1" height="48" width="64" class="slide--sm__img" />
        <span class="slide--sm__title">Slide 1</span>
      </li>
    </ul>
    

    That takes care of the initial offset, however to show the correct slides I disabled the focusOnSelect: true property and added an event listener instead:

    $slider_sm.on("click", "li.slide", function() {
      var slideNo = $(this).attr("data-sm-slide") - 1;
      $slider_lg.slick("slickGoTo", slideNo);
    })
    

    The corresponding slide index is taken from the data-* attribute and updates the main carousel; because that uses the asNavFor property, Slick takes care of the rest.