如果需要用js实现无缝轮播,请点传送门
用animation实现即表示是纯css实现,首先上效果图:
下面给出示例代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<style>
@keyframes slider {
0%{transform: translateX(0px);}
16%{transform: translateX(-200px);}
25%{transform: translateX(-200px);}
41%{transform: translateX(-400px);}
50%{transform: translateX(-400px);}
66%{transform: translateX(-600px);}
75%{transform: translateX(-600px);}
91%{transform: translateX(-800px);}
100%{transform: translateX(-800px);}
}
.container{width: 200px; height: 200px; overflow: hidden;}
.itemList{width: 9999px; margin: 0; padding: 0; border: 0; position: relative; font-size: 0;}
.itemListSlider{left: 0; animation: slider 3s linear infinite;}
.item{width: 200px; height: 200px; margin: 0; padding: 0; border: 0; display: inline-block;}
.item1{background-color: red;}
.item2{background-color: blue;}
.item3{background-color: yellow;}
.item4{background-color: green;}
</style>
<body>
<div class="container">
<ul class="itemList itemListSlider">
<li class="item item1"></li>
<li class="item item2"></li>
<li class="item item3"></li>
<li class="item item4"></li>
<li class="item item1"></li>
</ul>
</div>
</body>
</html>
下面列举一下几个需要注意的点:
ul元素的宽度设置要超过所有li元素宽度的总和(如示例中设置为9999px),保证所有li元素在同一行;
容器(即container)的高度和宽度与li元素的高度和宽度必须保持一致(保证容器在轮播停顿时可以正好展示一个li元素);
由于li元素通过设置display为inline-block保证所有li元素在同一行,此时必须设置ul元素的font-size为0,否则会导致li元素之间出现间隙;
为实现无缝轮播效果,必须额外增加一个li元素,这个额外增加的li元素应放在li元素列表末尾且与第一个li元素相同。
最后对slider中的百分比和translateX偏移的算法给出说明:
有n个li元素,则表示一个完整的轮播周期包含n-1个轮播动作(从一个li元素过度到下一个li元素的过程视为一个轮播动作),假设所有轮播动作的用时是一致的,则每个轮播动作的用时百分比应为1 / (n - 1) * 100%。以上例来说,有5个li元素,则表示一个轮播周期包含4个轮播动作,每个轮播动作的用时百分比为1 / (5 - 1) * 100%,即25%;
每个轮播周期的偏移量与li元素的宽度一致。以上例来说,第一个轮播动作(25%)时的偏移是-200px,第二个轮播动作(50%)时的偏移是-400px,以此类推;
如果希望一个轮播动作在执行完轮播后有短暂的停顿(即一个轮播动作包括从一个li元素过度到下一个li元素,以及短暂停顿一小会),以上例来说,如果一个轮播动作的时间为3s,而我们希望过度用时2s,然后停顿1s,则过度完成的时刻为25%的2/3(约为16%),写法如下:
0%{transform: translateX(0px);}
16%{transform: translateX(-200px);}
25%{transform: translateX(-200px);}
即轮播周期的0%到16%时间完成第一个轮播动作的过度效果,在接下来的16%到25%时间保持位置不变,后面的轮播动作依照这个写法处理即可。