Slick: Why is slick adding slick-cloned slides to my slider?

Created on 20 Jan 2015  路  26Comments  路  Source: kenwheeler/slick

Hi,

I have setup a slider with the correct js and markup as below:

<div class="books-slider">
        <% @books.shuffle.each do |book| %>
            <div class="slide <%= book.age %> <%= book.story_types.map(&:inspect).join(' ').gsub('"','').downcase %>" data-type="<%= book.story_types.map(&:inspect).join(', ').gsub('"','').downcase %>" data-title="<%= book.title %>" data-age="<%= book.age %>" data-author="<%= book.author.name %>">
              <%= link_to(book) do %>
                <div class="in">
                  <div class="book-jacket">
                    <%= image_tag book.jacket_cover.url %>
                  </div>
                </div>
              <% end %>
              <% if user_signed_in? %><%= link_to 'Destroy', book, method: :delete, style:'top: 0px;position: absolute;', data: { confirm: 'Are you sure?' } %><% end %>
              </div>
        <% end %>
      </div>

The above code basically runs through a loop and generates the slides from the loop and adds to them. Then I have the js that initiates the slider and gets data and inputs certain html in the slider:

$('.books-slider').slick({
                centerMode: true,
                centerPadding: '20px',
                slidesToShow: 1,
                adaptiveHeight: true,
                variableWidth: true,
                prevArrow: '.arrow-left',
                nextArrow: '.arrow-right',
                onInit: function(slide,index) {
                    var cr = $(slide.$slides.get(index));
                    var initTitle = cr.data('title'), 
                    initAuthor = cr.data('author'), 
                    initAge = cr.data('age'),
                    initType = cr.data('type');
                    $('.title-highlight h2.title').html(initTitle);
                    $('.title-highlight h2.author').html(initAuthor);
                    $('.title-highlight h2.age').html('Age: ' + initAge);
                    $('.title-highlight h2.type').html(initType);
                },
                onAfterChange: function(slide,index) {
                    var cr = $(slide.$slides.get(index));
                    var initTitle = cr.data('title'), 
                    initAuthor = cr.data('author'), 
                    initAge = cr.data('age'),
                    initType = cr.data('type');
                    $('.title-highlight h2.title').html(initTitle);
                    $('.title-highlight h2.author').html(initAuthor);
                    $('.title-highlight h2.age').html('Age: ' + initAge);
                    $('.title-highlight h2.type').html(initType);
                },
                responsive: [
                {
                  breakpoint: 768,
                  settings: {
                    arrows: false,
                    centerMode: true,
                    centerPadding: '40px',
                    slidesToShow: 3
                  }
                },
                {
                  breakpoint: 480,
                  settings: {
                    arrows: false,
                    centerMode: true,
                    centerPadding: '40px',
                    slidesToShow: 1
                  }
                }
                ]
            });

When I load the page I see that the slides have been cloned. There are only meant to be 2 at this current moment.

Here is what I see in the inspector:

screen shot 2015-01-20 at 16 10 28

Can anyone please help me here?

Thanks

Most helpful comment

But what if I want the infinite slideshow but without html clones ?

All 26 comments

@mdunbavan thanks for contributing 馃槉

The cloned items are because you have an infinite carousel with 3 slides to show and in center mode. What this means is that Slick needs to place "clones" of those slides at each end of the carousel so that when you approach the end it has a copy to display at the beginning as it "infinitely" goes around.


Curiously; what exactly is your problem, and what is the bug with the plugin which you are creating an issue for? :smile: -- if none please kindly close the issue.

Regards, Simon.

I don't know whether to open a new issue or reopen this issue. The problem for me is that when I run the WAVE accessibility tool in Chrome, the cloned slides create alerts that say, "A nearby image has the same alternative text."

It was doing same for me! I solved with setting infinite to false:

$(document).ready(function(){
$('.swipe-container').slick({
dots: true,
arrows: false,
swipeToSlide: true,
infinite: false
});
});

@gretak Thanks. infinite: false worked for me.

But what if I want the infinite slideshow but without html clones ?

For those willing to hide (or do anything else to) the cloned items in a specific moment, there is a CSS hook: .slick-cloned

@linorabolini Regarding your question: using .slick-cloned { display: none !important; } on a slick carousel with infinite:true set (default setting I believe) will break it. So my assumption is that infinite slideshow without html clones is probably not possible with the current code (Version: 1.6.0 - October 2016) otherwise @simeydotme would have provided info abt this in the exhaustive (pretty awesome) documentation.

.slick-cloned slides break React's mouse events like onMouseEnter and onMouseLeave. Turning infinite off fixed it but I still want infinite slides :(

Having the same issue as g0ddish but with AngularJS

@decodedcreative It is likely related to how they use synthetic events and not native events. Not that I have a solution yet but hopefully that gets us going in the right direction...

Hy, same issue but the first element of my slider is a vid茅o with autoplay... so when a clone of this slide is created, I have a double sound on background..

Same here as @redacherifi ... That really sucks. You can remove the video clone with JS but then on Safari this slide won't show.

Solution around @simeydotme @kenwheeler ?
Plz reopen.

I've come across the same issue today. It's mainly a problem with video. Never had a problem in the past.

Something simple as the below:

let slick_index = $('.slideshow--product').find('.slideshow__slide--video').data( 'slick-index' );

if( slick_index !== this.$slideshow.slick('slickCurrentSlide') ) {
    this.$slideshow.slick( 'slickGoTo', slick_index );
}

This returns incorrectly as slick_index keep returning -1 as the first slide it finds with that class has been cloned. So it's returning the cloned version.

Ok let's open a new issue, seems not that this one got a reopen.

@CHEWX @redacherifi New issue here: https://github.com/kenwheeler/slick/issues/2751

One faces the same problem using Ember.js (as React/Angular) when either playing video in the slide or showing dynamically changing content. Anyone know a good workaround for this when one wants an Infinite scroll?

When 2 slick carousel (one have only 1 slide in view other have many, acting as thumb) are in sync & I have a click event on thumbs which re-adjust top carousel on click event, but if the clicked thumb is a cloned version then it gives me negatives slick index which I am able to calculate to the proper one but then thumbs animate all the way to the other side to show non-cloned version. This animation that instead of centering cloned version is going to the non-cloned version is annoying.

here is my code if above statement didn't made sense.

var expCarouselTotalItems = $('.js-carousel-exp-thumb img').length;
$('.js-carousel-exp-thumb').slick({
    slidesToShow: 7,
    slidesToScroll: 1,
    centerMode: true,
    asNavFor: '.js-carousel-exp',
});

$('.js-carousel-exp-thumb .exp-thumb-item').click(function (e) {
    e.preventDefault();
    var thisSlideIndex = $(this).closest('[data-slick-index]').attr('data-slick-index');
    if(thisSlideIndex<0){
        thisSlideIndex = (expCarouselTotalItems - Math.abs(thisSlideIndex));
    }
    $('.js-carousel-exp').slick('slickGoTo', thisSlideIndex);
});

$('.js-carousel-exp').slick({
    slidesToShow: 1,
    arrows: false,
    swipe: false,
    fade: true,
    asNavFor: '.js-carousel-exp-thumb'
});

If you don't need the dots, you can just duplicate the set of slides, and you won't get cloned slides.

A simple condition as boolean solved it for me.

{
                infinite: pictures.length > 3,
                slidesToShow: 4,
                slidesToScroll: 1,
            }

One way to reach inifinity without clones is going back to slide 0 when the last slide is reached.

  $('#mainSlider').on('afterChange', function(event, slick, currentSlide, nextSlide){
    mainSlider = slick;
    if((slick.slideCount - 1) == currentSlide){
      setTimeout(function(){
        mainSlider.goTo(0);
      }, mainSlider.getOption('autoplaySpeed'));
    }
  });

Another reason why cloning might be an issue for a developer - duplicate content is bad for SEO :)

Another reason why cloning might be an issue for a developer - duplicate content is bad for SEO :)

SEO is server-side, not client-side. Clone is done on the client-side.

N

Another reason why cloning might be an issue for a developer - duplicate content is bad for SEO :)

SEO is server-side, not client-side. Clone is done on the client-side.

Not if you use server side rendering. You can check it with a free tool like https://www.seobility.net/de/seocheck/ if there is duplicate content on your page.

Well, that's the exception to the rule, yes.

Adding to this as I feel it's relevant -

I'm hitting a scenario where I need an infinite carousel in centre mode, and every visible slide must be clickable. When the last slide in the array is in the leftmost visible position, or the first in the array is in the rightmost, they will be both active and clones, and therefore not clickable.

slick-issue

Has anybody else encountered anything like this?

Adding to this as I feel it's relevant -

I'm hitting a scenario where I need an infinite carousel in centre mode, and every visible slide must be clickable. When the last slide in the array is in the leftmost visible position, or the first in the array is in the rightmost, they will be both active and clones, and therefore not clickable.

slick-issue

Has anybody else encountered anything like this?

Yes, but you can use JavaScript and check is element has cloned class, if so, get next.

One way to reach inifinity without clones is going back to slide 0 when the last slide is reached.

  $('#mainSlider').on('afterChange', function(event, slick, currentSlide, nextSlide){
    mainSlider = slick;
    if((slick.slideCount - 1) == currentSlide){
      setTimeout(function(){
        mainSlider.goTo(0);
      }, mainSlider.getOption('autoplaySpeed'));
    }
  });

Thank's this is perfectly working. Pointing back to the first index 馃憤

Was this page helpful?
0 / 5 - 0 ratings