光滑的滑块 - 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>
在无限循环中,您有用户 odd
和 even
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 过渡无限循环错误的主要内容,如果未能解决你的问题,请参考以下文章