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

Posted

技术标签:

【中文标题】光滑的滑块 - css 过渡无限循环错误【英文标题】:slick slider - css transition infinite loop bug 【发布时间】:2018-01-06 10:18:21 【问题描述】:

我有一个使用光滑滑块设置的滑块。当使用下一个和上一个按钮时,该项目以一个很好的过渡进入查看。我遇到的问题是,当它重新启动循环时,第一项“捕捉”到视图中,而不是进行转换。此外,随着css“奇数”和“偶数”类的变化,它似乎失去了内部索引。见下面的 sn-p:

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

我想我知道它为什么这样做,因为它必须创建“克隆”项目才能使无限循环功能起作用。我尝试了几个不同的滑块插件,它们似乎都有类似的问题。

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

【问题讨论】:

Flickity 滑块似乎没有“捕捉”问题。至于奇数/偶数样式问题,您可以这样做:如果您有奇数个项目,请复制列表。见this jsfiddle。 看起来不错,我试试看! 【参考方案1】:

解决方案 1 - 使用 Flickity

如果您想尝试其他轮播控件,可以查看Flickity。根据我对 wrapAround 选项的测试,当整个循环完成时,它不会将第一个项目“弹回”到位;过渡顺利进行。你可以在this jsfiddle看到它的工作。

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

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,为过渡添加延迟有助于在循环完成时使其更平滑。在下面的代码sn-p中,我换成了:

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>

【讨论】:

我修改了我的答案,为光滑的滑块提供了一个解决方案。 我将您的解决方案用于 Flickity 滑块,这就是我所采用的。谢谢:) 很好的解决方案,只需添加 transition-delay 即可解决问题。很好学这个。投票【参考方案2】:

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

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

Slick 实施之前的代码

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

Slick 实施后的代码

<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 时间,则它不会捕捉您的浏览器。

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

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

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

请在下面查看我的 sn-p。

$(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 中的幻灯片数量,则不会发生这种情况。

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

【讨论】:

这解决了样式问题(以一种公认的聪明方式),但是,第一张幻灯片仍然卡入到位,而您似乎声称您已经解决了它。 @Patrick :再次阅读我的答案,我提到了正在发生的事情,我试图解释它为什么会突然发生。我从来没有声称我解决了它,我只是给出了另一种处理方式。【参考方案3】:

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

如果您有兴趣,这里有一个基于过渡的滑块概念验证,它不克隆任何东西,只是改变位置。也有可能通过order 实现相同的目标 - 尚未尝试但现在考虑了。

https://codepen.io/prowseed/pen/QMEQxg - 当然,它需要做很多工作才能使其完全可用,但我试图让它具有响应性并且与您的示例最相似。您只需跟踪索引即可添加/删除某些类(例如.current)。

【讨论】:

【参考方案4】:

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

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 在其正文中替换调用

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

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

【讨论】:

如果能修复它会很棒。唉,它没有。 这适用于转到下一张幻灯片,但在转到上一张幻灯片时故障仍然存在。你能修补这个补丁吗?两个方向都可以工作会很棒!【参考方案5】:

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"] 


【讨论】:

【参考方案6】:

@Maciej Kwas

这可能是一项功能,但在此站点上,当您使用“中心模式”查看滑块时,它工作正常,从最后一张幻灯片滑到第一张幻灯片时动画看起来不错。 http://kenwheeler.github.io/slick/

【讨论】:

【参考方案7】:

由于我无法摆脱过去,我仍在使用 Slick。我遇到了这个问题,结果发现问题是我的滑块图像使用了srcset 属性。删除修复了问题。

【讨论】:

【参考方案8】:

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

我发现添加以下内容提供了一个没有故障的无限循环

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

【讨论】:

无限?真的是男人吗? @BabkenAsryan 是的,非常适合我。 有这样的功能吗? 这可以访问我发现检查正在使用的 Slick Slider 的 .slick-track 类,这就是我认为它被接受的原因。

以上是关于光滑的滑块 - css 过渡无限循环错误的主要内容,如果未能解决你的问题,请参考以下文章

光滑的轮播 JS 库在第一张幻灯片上堆叠所有内容

无限时禁用光滑的克隆幻灯片:true

如何使用 css 变换创建循环过渡动画

使用 CSS 的无限图标滑块

Jquery简单的无限循环滑块逻辑

光滑的滑块工作正常,但在控制台中出现不必要的错误 [我想解决它]