Tiny-slider: How to target center slide?

Created on 3 Jul 2019  路  14Comments  路  Source: ganlanyuan/tiny-slider

I need to apply custom CSS to a center slide. The slider appears to not have any class that would identify it as a center slide. How do I target the center slide?

question

Most helpful comment

I've approached this using CSS for my carousel which has 3 slides visible. I have all my slides opacity property set to .5 and wish for the centered one to be 1.

.tns-item:not(.tns-slide-active) + .tns-slide-active + .tns-slide-active { opacity: 1; }

First find the slide that is not active, then find the slide that is active and then target the slide immediately after (the one that is centered).

This can end up being quite cumbersome if you have multiple slides on display, but does allow you to use CSS transitions where needed and not have to rely on the events that can cause the slides to flicker.

All 14 comments

I've approached it by applying an active class to the index of the slides that matches the slider.getInfo().index property on the transitionStart or transitionEnd events.

However, in loop mode the slides get fully replaced when you navigate far enough in either direction and I haven't found a suitable event that will let me reapply my active classes to the new layout - the rearranging happens after transitionEnd. It's a bit janky.

edit: I misremembered- the indexChanged event will fire but in my case I get a flicker where my center class is lost then instantly added.

I've approached this using CSS for my carousel which has 3 slides visible. I have all my slides opacity property set to .5 and wish for the centered one to be 1.

.tns-item:not(.tns-slide-active) + .tns-slide-active + .tns-slide-active { opacity: 1; }

First find the slide that is not active, then find the slide that is active and then target the slide immediately after (the one that is centered).

This can end up being quite cumbersome if you have multiple slides on display, but does allow you to use CSS transitions where needed and not have to rely on the events that can cause the slides to flicker.

You can easily add a class using a event. For example:

slider.events.on("transitionEnd", function(info) {
  info.slideItems[info.indexCached].classList.remove(
    "your-class-here"
  );

  info.slideItems[info.index].classList.add(
    "your-class-here"
  );
});

Thank you @wadtech @codetopixels @arjenblokzijl
@dmxd5 You could use transitionStart or transitionEnd events to get the index of the first active slide, then get the center slider based on how many slides on one page.

transitionStart/End don't work when the slides reset with the loop option on, and there's no event for when the loop resets - any classes added are stuck.

@codetopixels css solution works. transitions on any of the child items would have to be disabled in the same way as tns does to its inner

indexChanged fires after the loop resets, but there's something funny going on with indexCached.

$(document).ready(() => {
  const slider = tns({
    container: '.donut-slider',
    items: 4,
    slideBy: "page",
    loop: true,
    controls: false,
    center: true,
    mouseDrag: true,
    swipeAngle: false,
    speed: 700,
  });

  slider.getInfo().slideItems[slider.getInfo().index].classList.add('donut-slider_item--active');
  slider.events.on('indexChanged', () => {
    const info = slider.getInfo();
    const indexPrev = info.indexCached;
    const indexCurr = info.index;
    console.log(indexPrev, indexCurr);
    info.slideItems[indexPrev].classList.remove('donut-slider_item--active');
    info.slideItems[indexCurr].classList.add('donut-slider_item--active');
  });
});

Results:

  • when the loop resets, the previous item still has the donut active class.
  • indexPrev never updates when the loop resets - the indexCached value, in this case, remains four.
7 6 compiled.js:1:3572
6 5 compiled.js:1:3572
5 4 compiled.js:1:3572
4 3 compiled.js:1:3572
4 10

I get why transitionStart/End don't do this, but I feel like indexChanged should pop the indexCached value. Would also nice for the transition-duration:0 be applied to a class rather than an inline style, so child items can look to the class to have their own transition durations changed to 0.

This can end up being quite cumbersome if you have multiple slides on display, but does allow you to use CSS transitions where needed and not have to rely on the events that can cause the slides to flicker.

@codetopixels

I applied it like

.container .tns-item {
  opacity: .2;
}
.container .tns-item:not(.tns-slide-active) + .tns-slide-active + .tns-slide-active { 
  opacity: 1; 
}

and it worked so this means you can change slider. Thanks.

@minaminfo really buggy css...

Is there a better solution and maybe official support when using center: true ?

@ganlanyuan Can you reopen the issue? For me it is not solved and it would be great if there is official support for center items like in owl carousel

I've approached this using CSS for my carousel which has 3 slides visible. I have all my slides opacity property set to .5 and wish for the centered one to be 1.

.tns-item:not(.tns-slide-active) + .tns-slide-active + .tns-slide-active { opacity: 1; }

First find the slide that is not active, then find the slide that is active and then target the slide immediately after (the one that is centered).

This can end up being quite cumbersome if you have multiple slides on display, but does allow you to use CSS transitions where needed and not have to rely on the events that can cause the slides to flicker.

Unfortunately this does not work if the slider is looped.

Use the changes applied in pull requests #638 or #670
@katsar0v @thenomadicmann

I had the problem with a slider that had a transition transform scale effect so I needed to put the .active class beforehand to avoid the shrink/scale effect and I came up with this (its not pretty):

let servicesSlider = tns({
    container: ".slider-services",
    items: 3,
    slideBy: 1,
    autoplay: false,
    gutter: 30,
    loop: true,
});

let index;
servicesSlider.events.on("indexChanged", () => {
    const info = servicesSlider.getInfo();
    const originalCount = info.slideCount;
    const allCount = info.slideCountNew;
    const itemsCount = info.items;
    const indexCurrent = info.index;
    if (index !== indexCurrent) {
        index = indexCurrent;
        if (index === 1) {
            info.slideItems[originalCount + 1].classList.add("active");
        } else if (index === allCount - itemsCount) {
            info.slideItems[allCount - itemsCount - originalCount + 1].classList.add("active");
        }
    }
});

I get rid of the .active class in my goTo("next/"prev) logic. So far it works with 3 items displayed no matter what the number of slides is, I tried for 5 items displayed and it was out of index but you can tweek it to your taste.

Was this page helpful?
0 / 5 - 0 ratings