slick slider - css transition infinite loop bug

后端 未结 6 1509
傲寒
傲寒 2021-02-04 04:59

I\'ve got a slider set up using slick slider. When using the next and previous buttons, the item comes in to view with a nice transition. The problem I\'m having is that when it

相关标签:
6条回答
  • 2021-02-04 05:22

    Here my hack for slick.js Warning!! use its carefully, cause its alter source code of plugin

    1) Find function
    Slick.prototype.setSlideClasses and replace its definition from

     Slick.prototype.setSlideClasses = function(index) 
    

    to

    Slick.prototype.setSlideClasses = function(index, oldSlide)
    

    2) in body of this function after code

    _.$slides
        .eq(index)
        .addClass('slick-current');
    

    add

    if(oldSlide!=undefined){
        if(index==0 && oldSlide!=1){
            var _current = this.$slides.eq(this.$slides.size()-1);
            var __index = allSlides.index(_current);
            var ss = allSlides.eq(__index+1);
            ss.addClass('slick-current');
        }
        if(index==this.$slides.size()-1 && oldSlide!=this.$slides.size()-2){
            var _current = this.$slides.eq(0);
            var __index = allSlides.index(_current);
            var ss = allSlides.eq(__index-1);
            ss.addClass('slick-current');
        }
    }
    

    3) find function Slick.prototype.slideHandler in its body replace call

    oldSlide = _.currentSlide;
    _.currentSlide = animSlide;
    _.setSlideClasses(_.currentSlide);
    

    to

    oldSlide = _.currentSlide;
    _.currentSlide = animSlide;
    _.setSlideClasses(_.currentSlide,oldSlide);
    
    0 讨论(0)
  • 2021-02-04 05:26

    @GSTAR, Eventually there is no error in your code but there is bit css and js flow you need to understand while using slick.

    Slick is cloning your slides and amend in top and down of your slide. like describe below.

    Your Code before Slick implementation

    <ul class="items">
        <li class="item"><div class="content"><span>1</span></div></li>
        <li class="item"><div class="content"><span>2</span></div></li>
        <li class="item"><div class="content"><span>3</span></div></li>
        <li class="item"><div class="content"><span>4</span></div></li>
        <li class="item"><div class="content"><span>5</span></div></li>
        <li class="item"><div class="content"><span>6</span></div></li>
    </ul>
    

    Your Code After Slick implementation

    <ul class="items">
        <li class="item slick-cloned"><div class="content"><span>4</span></div></li>
        <li class="item slick-cloned"><div class="content"><span>5</span></div></li>
        <li class="item slick-cloned"><div class="content"><span>6</span></div></li>
    
        <li class="item"><div class="content"><span>1</span></div></li>
        <li class="item"><div class="content"><span>2</span></div></li>
        <li class="item"><div class="content"><span>3</span></div></li>
        <li class="item"><div class="content"><span>4</span></div></li>
        <li class="item"><div class="content"><span>5</span></div></li>
        <li class="item"><div class="content"><span>6</span></div></li>
    
        <li class="item slick-cloned"><div class="content"><span>1</span></div></li>
        <li class="item slick-cloned"><div class="content"><span>2</span></div></li>
        <li class="item slick-cloned"><div class="content"><span>3</span></div></li>
    </ul>
    

    Also after adding this your animation code is working fine. but it can not visually visible. if you increase this animation time than it will not snaps your browser.

    If you replace javascript code than you will come to know what is happening.

    <script type="text/javascript">
        $(document).ready(function() {
            $('.items').slick({
                centerMode:true,
                slidesToShow: 3,
                speed: 500,
                infinite: true,
                cssEase: 'linear',
                variableWidth: true
            });
        });
    </script>
    

    So after loop get finished and reaching to the first slide animation executed and before reach it get finished.

    Please check below my snippet.

    $(document).ready(function() {
        $('.items').slick({
            slidesToShow: 2,
            speed: 500
        });
    });
    * {
      margin: 0;
      padding: 0;
    }
    
    ul {
      list-style: none;
      height: 150px;
    }
    
    .slick-list, .slick-track {
      height: 100%;
    }
    
    ul li {
      width: 350px;
      height: 100%;
    }
    
    ul li .content {
      width: 100%;
      height: 100%;
      transition: transform 0.5s linear;
      transition-delay: 0.5s;
      text-align: center;
    }
    
    ul li .content span {
      color: #fff;
      font-size: 50px;
      font-family: Arial;
      position: relative;
      top: 50%;
      transform: translateY(-50%);
      display: block;
    }
    
    ul li:nth-child(odd) .content {
      background-color: red;
    }
    
    ul li:nth-child(even) .content {
      background-color: green;
    }
    
    ul li:not(.slick-current) .content {
      transform: scale(0.9);
    }
    <link href="https://cdn.jsdelivr.net/jquery.slick/1.6.0/slick.css" rel="stylesheet"/>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://cdn.jsdelivr.net/jquery.slick/1.6.0/slick.min.js"></script>
    <ul class="items">
      <li class="item">
        <div class="content">
          <span>1</span>
        </div>
      </li>
    
      <li class="item">
        <div class="content">
          <span>2</span>
        </div>
      </li>
    
      <li class="item">
        <div class="content">
          <span>3</span>
        </div>
      </li>
    
      <li class="item">
        <div class="content">
          <span>4</span>
        </div>
      </li>
    
      <li class="item">
        <div class="content">
          <span>5</span>
        </div>
      </li>
      <li class="item">
        <div class="content">
          <span>6</span>
        </div>
      </li>
    </ul>

    In infinite loop you have user odd and even css so as per the loop it your next first slide(cloned slide) has green color but your original slide(first slide) has red color hence it flicking color also. If you use number of slides in %2, then this will not happen.

    Hope it will help you to understand better.

    0 讨论(0)
  • 2021-02-04 05:34

    Infinity set to true, CenterMode set to false add effect to current just css

    /* slide when not active*/ 
    .slick-slide[aria-hidden="true"]:not(.slick-cloned) ~ .slick-cloned[aria-hidden="true"] {
    
    }
    
    /* slide when active (when play last to first) */ 
    .slick-slide[aria-hidden="true"]:not([tabindex="-1"]) + .slick-cloned[aria-hidden="true"]  {
    
    }
    /* slide when active (when play first to last) */ 
    .slick-slide[aria-hidden="true"] + .slick-cloned[aria-hidden="true"] {
    
    }
    
    0 讨论(0)
  • 2021-02-04 05:36

    @Maciej Kwas

    It might be a feature but on this site when you look on slider with "Center Mode" it works fine, the animation looks OK when sliding from last to first slide. http://kenwheeler.github.io/slick/

    0 讨论(0)
  • 2021-02-04 05:39

    This is not an issue, it's a feature - this is just how slick slider (and most of other infinite-loop sliders) works. Basically, if slider would only clone divs it would end up with a huge performance issue, thus in certain places (beginning/end) after animation it rerender whole thing to start over.

    If you are interested here is a proof-of-concept of slider that is based on transition and does not clone anything, just changes positions. Also maybe there is possibility to achieve the same with order - haven't tried but thought about it now.

    https://codepen.io/prowseed/pen/QMEQxg - of course it requires a lot of work to make it fully usable, but I tried to make it responsive and the most similar to your example. You just have to keep track of index to add/remove certain classes (.current for example).

    0 讨论(0)
  • 2021-02-04 05:45

    Solution 1 - Use Flickity

    If you want to try another carousel control, you can have a look at Flickity. According to my tests with the wrapAround option, it does not "snap" the first item back into position when the full cycle is complete; the transition goes on smoothly. You can see it at work in this jsfiddle.

    As for the problem with formatting the items according to their even/odd index, it happens only when you have an odd number of items. One solution would be to duplicate the list of items. Intead of

    Item 1 / Item 2 / Item 3 / Item 4 / Item 5
    

    you could define

    Item 1 / Item 2 / Item 3 / Item 4 / Item 5 / Item 1 / Item 2 / Item 3 / Item 4 / Item 5
    

    That would ensure that you work with an even number of items.


    Solution 2 - Slick Slider: add transition delay

    With Slick Slider, adding a delay to the transition helps to make it smoother when the cycle completes. In the code snippet below, I replaced:

    ul li .content {
      transition: transform 0.5s linear;
      ...
    }
    
    ul li:not(.slick-current) .content {
      transform: scale(0.9);
    }
    

    with

    ul li .content {
      transition: transform 0.3s linear;
      transition-delay: 0.5s;
      ...
    }
    
    ul li:not(.slick-current) .content {
      transform: scale(0.9);
      transition-delay: 0s;
    }
    

    $(document).ready(function() {
      $('.items').slick({
        infinite: true,
        speed: 500,
        slidesToShow: 2,
        variableWidth: false
      });
    });
    * {
      margin: 0;
      padding: 0;
    }
    
    ul {
      list-style: none;
      height: 150px;
    }
    
    .slick-list,
    .slick-track {
      height: 100%;
    }
    
    ul li {
      width: 350px;
      height: 100%;
    }
    
    ul li .content {
      width: 100%;
      height: 100%;
      transition: transform 0.3s linear;
      transition-delay: 0.5s;
      text-align: center;
    }
    
    ul li .content span {
      color: #fff;
      font-size: 50px;
      font-family: Arial;
      position: relative;
      top: 50%;
      transform: translateY(-50%);
      display: block;
    }
    
    ul li:nth-child(odd) .content {
      background-color: red;
    }
    
    ul li:nth-child(even) .content {
      background-color: green;
    }
    
    ul li:not(.slick-current) .content {
      transform: scale(0.9);
      transition-delay: 0s;
    }
    <link href="https://cdn.jsdelivr.net/jquery.slick/1.6.0/slick.css" rel="stylesheet" />
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://cdn.jsdelivr.net/jquery.slick/1.6.0/slick.min.js"></script>
    <ul class="items">
      <li class="item">
        <div class="content">
          <span>1</span>
        </div>
      </li>
      <li class="item">
        <div class="content">
          <span>2</span>
        </div>
      </li>
      <li class="item">
        <div class="content">
          <span>3</span>
        </div>
      </li>
      <li class="item">
        <div class="content">
          <span>4</span>
        </div>
      </li>
      <li class="item">
        <div class="content">
          <span>5</span>
        </div>
      </li>
      <li class="item">
        <div class="content">
          <span>1</span>
        </div>
      </li>
      <li class="item">
        <div class="content">
          <span>2</span>
        </div>
      </li>
      <li class="item">
        <div class="content">
          <span>3</span>
        </div>
      </li>
      <li class="item">
        <div class="content">
          <span>4</span>
        </div>
      </li>
      <li class="item">
        <div class="content">
          <span>5</span>
        </div>
      </li>
    </ul>

    0 讨论(0)
提交回复
热议问题