kenwheeler / slick

the last carousel you'll ever need
kenwheeler.github.io/slick
MIT License
28.54k stars 5.89k forks source link

focusOnSelect doesn't work when a filter is applied to synced sliders #1043

Open a0c opened 9 years ago

a0c commented 9 years ago

A very simple issue which could be simulated like this:

Set up

Once the filter has been applied to both sliders, clicking on slider-nav items should navigate to the same items in slider-for. Instead, Slick navigates to a wrong item, in some crazy manner.

Test Case

Try clicking on slide3 text => and then on slide7 in this jsFiddle test case.

Bug Explanation

Slide attribute data-slick-index, which is used for navigation, cannot be relied on once a filter has been applied. Natural order of slides should be used instead. Fix is to follow...

oxyc commented 9 years ago

I encountered this issue as well and the patch is still good.

Nevermind it solves the particular problem but breaks once the slider is unfiltered again.

BenMGilman commented 9 years ago

+1

sebastiancichos commented 8 years ago

I have the same issue in 1.5.9 version. Anyone can help? I need this to my project

Tailzip commented 8 years ago

I'm having this issue too

incredimike commented 8 years ago

I think I am also having this issue.

Flicksie commented 8 years ago

still having this issue in 1.6

another solution could be reassign the entire index upon filtering

Flicksie commented 8 years ago

achieved some fishy solution by inserting _.$slides.each(function(index, element) { $(element).attr('data-slick-index', index); }); at line 1799, inside the reinit function. not sure about side-implications of this method, use at own risk

sleepygarden commented 8 years ago

@LucasFlicky That solve really saved me, I'm using a slick nav by asNavFor. When I use slickFilter nothing gets reindexed, so click on a filtered nav slide causes both the main slick and the nav to jump around erratically. I shimmed in your code at the end of the function:

var oldReinit = $('#video-nav-container').slick('getSlick').reinit;
var newReinit = function reinitOverride(){
    this._overriddenReinit();
    this.$slides.each(function(index, element) { $(element).attr('data-slick-index', index); });
};
$('#video-nav-container').slick('getSlick')._overriddenReinit = oldReinit;
$('#video-nav-container').slick('getSlick').reinit = newReinit;
Colir commented 7 years ago

+1 i've made a codepen to illustrate the problem. http://codepen.io/Colir/pen/YNePyM thanks

Colir commented 7 years ago

base on the solution of @LucasFlicky , here is a working version without plugin's core modifications http://codepen.io/Colir/pen/PWQqEE

tsymbal commented 7 years ago

My variant of solution, based on previous "codepens".

.gallery_slider - main slider .gallery_thumbs - thumbs slider .filternav ul li a - filter links (albums), their href="#id" (id = album id), all slides (in both sliders) have id as "class" value. So, each slide can be in several albums. For example, clicking on link with href="#dir1" will filter all slides (in both sliders), that have class="... dir1 ..."

    $('.gallery_slider').slick({
        slidesToShow: 1,
        slidesToScroll: 1,
        arrows: true,
        fade: false,
        infinite: false,
        asNavFor: '.gallery_thumbs'
    });
    $('.gallery_thumbs').slick({
        slidesToShow: 4,
        slidesToScroll: 1,
        infinite: false,
        asNavFor: '.gallery_slider',
        dots: false,
        centerMode: false,
        focusOnSelect: true,
        arrows: true,
    });
    $(document).on('click', '.filternav ul li a', function(a){
        a.preventDefault();
        $(".filternav ul li").removeClass("active");
        $(this).parents("li").addClass("active");
        href = $(this).attr("href").replace("#","");
        console.log(href);
        var $slider = $('.gallery_slider, .gallery_thumbs');
        $slider.slick('slickUnfilter').slick('slickFilter','.'+href);
        $slider.each(function(index,slide){
            s_id = 0;
            //console.log(index,slide,s_id);
            $(".slick-slide:not(.slick-cloned)",slide).each(function(s_index,s_slide) {
                $(this).attr("data-slick-index",s_id)
                s_id = s_id+1;
                if (index==0) {
                    if ($(this).hasClass("slick-current")) {
                        active_index = s_id;
                    }
                }
                if (index==1) {
                    if (s_id==active_index) {
                        $(this).addClass("slick-current");
                    } else {
                        $(this).removeClass("slick-current");
                    }
                }
            })
        })
        $slider.slick('slickGoTo',0,true);
    });