光滑的滑块 - css 过渡无限循环错误

slick slider - css transition infinite loop bug

我已经使用 slick slider 设置了一个滑块。使用下一个和上一个按钮时,项目会以漂亮的过渡进入视图。我遇到的问题是,当它重新开始其循环时,第一项 "snaps" 进入视图,而不是进行转换。此外,它似乎失去了内部索引,因为 css "odd" 和 "even" 类 已更改。请参阅下面的代码段:

$(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;
  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>
</ul>

我想我知道它为什么要这样做,因为它必须创建 "cloned" 项才能使无限循环功能正常工作。我尝试了几个不同的滑块插件,它们似乎都有类似的问题。

有谁知道我该如何解决这个问题? jsfiddle 在这里:https://jsfiddle.net/7kdmwkd9/1/

这不是问题,它是一项功能 - 这就是 slick 滑块(以及大多数其他无限循环滑块)的工作原理。基本上,如果滑块只克隆 div,它最终会出现巨大的性能问题,因此在某些地方 (beginning/end) 在动画之后它会重新渲染整个事情以重新开始。

如果您感兴趣,这里是滑块的概念验证,它基于转换并且不克隆任何东西,只是改变位置。也有可能用 order 实现同样的效果 - 没有尝试过但现在考虑了。

https://codepen.io/prowseed/pen/QMEQxg - 当然需要大量工作才能使其完全可用,但我尝试使其具有响应性并且与您的示例最相似。您只需要跟踪 add/remove 某些 类 的索引(例如 .current)。

解决方案 1 - 使用 Flickity

如果你想尝试另一个轮播控件,你可以看看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

至于根据项目 even/odd 索引格式化项目的问题,只有当项目数量为奇数时才会发生。一种解决方案是复制项目列表。取而代之

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

你可以定义

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

这将确保您处理的项目数量是偶数。


解决方案 2 - Slick Slider:添加过渡延迟

使用 Slick Slider,向过渡添加延迟有助于在循环完成时使其更平滑。在下面的代码片段中,我替换了:

ul li .content {
  transition: transform 0.5s linear;
  ...
}

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

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>

@GSTAR,最终你的代码没有错误,但是有一点css和你在使用slick时需要理解的js流程。

Slick 正在克隆您的幻灯片并在幻灯片的顶部和底部进行修改。如下所述。

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>

此外,在添加此代码后,您的 animation 代码工作正常。但它不能在视觉上可见。如果你增加这个 animation 时间,它不会 snaps 你的浏览器。

如果您替换 javascript 代码,您就会知道发生了什么。

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

因此在循环完成并到达执行的第一个幻灯片动画之后,在到达之前完成。

请检查下面我的代码段。

$(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>

在无限循环中,您有用户 oddeven css,因此根据循环,您的下一张 first 幻灯片(克隆幻灯片)是绿色的,但您的原始幻灯片(第一张幻灯片)具有红色,因此它也闪烁颜色。如果您在 %2 中使用幻灯片数量,则不会发生这种情况。

希望它能帮助你更好地理解。

@Maciej Kwas

这可能是一项功能,但在本网站上,当您使用 "Center Mode" 查看滑块时它工作正常,从最后一张幻灯片滑动到第一张幻灯片时动画看起来不错。 http://kenwheeler.github.io/slick/

这是我的技巧 slick.js 警告!!小心使用它,导致它改变插件的源代码

1) 查找函数
Slick.prototype.setSlideClasses 并替换它的定义 来自

 Slick.prototype.setSlideClasses = function(index) 

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

2) 在代码后的函数体中

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

添加

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) 查找函数Slick.prototype.slideHandler 在它的正文中替换 call

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

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

Infinity 设置为 true,CenterMode 设置为 false 为电流添加效果 只是 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"] {

}

我找到了一个非常简单的解决方案来解决我的问题版本,即一旦所有 4 张幻灯片都完成后,它会积极循环/错误。

我发现添加以下内容可提供无故障的无限循环

.slick-track {
transition: fade 2000ms ease-out;  
infinite: true;  
}

因为我很难放下过去,所以我仍在使用 Slick。我遇到了这个问题,结果发现问题是我的滑块图像使用了 srcset 属性。删除解决了问题。