之所以想要写原生js配合css转换的无缝滚动,是因为之前在简书上看到一哥们写的一篇文章,说是在网上找了一堆js配合css transition属性写的轮播插件,可惜没有无缝的效果,结果他用原生js重写了一个可以无缝滚动的。好吧,我觉得这哥们的精神还是值得表扬的,只是原生实现略显麻烦,也很难把握性能(利用定时器写的动画很容易有性能问题)。
原生JavaScript无缝轮播图特效 附上链接方便大家一同对比学习
其实原生js配合css转换写个无缝滚动要比直接用原生js写起来简单得多,而且性能非常好。希望通过这篇文章能起到抛砖引玉的笑果!哈哈哈哈,二话不说,上码!!!
首先附上相应的HTML和CSS:
html
<div class="box">
<ul id="box">
<li>158****546已购买1个月</li>
<li>158****546已购买2个月</li>
<li>158****546已购买3个月</li>
<li>158****546已购买4个月</li>
<li>158****546已购买5个月</li>
<li>158****546已购买1个月</li>
</ul>
</div>
css
.box{
width: 300px;
height: 40px;
overflow: hidden;
border: 1px solid rebeccapurple;
}
.box>ul{
margin: 0;
padding: 0;
}
.box>ul>li{
list-style-type: none;
width: 300px;
height: 40px;
line-height: 40px;
}
.count{
font-size: 24px;
}
细心的朋友可能会发现HTML上面首尾两个li是一样的(哈哈哈,就是说明一下它俩是一样的)上图!!啊哈哈哈哈,将就看一下,我画了好久的。这里为了节约空间就横着放了,下面的例子的滚动是向上走的。
当焦点位于图片1的副本(即红框那个1)时,那一瞬间让整个列表回到初始的位置,即第一个1在红框内。对,最后面这个副本1就是为了让用户产生视觉差。
下面开始编写相应的js,先写一个构造函数,然后把获取的id以及向上滑动的数值作为私有变量写死在构造函数里面:
function sliderBox() {
var list = document.getElementById('box'),
newPosition = 0, //这里以ul作为位移目标,newPosition为ul每次的位置
offset = -40; //每次要上移的数值(先默认为上移)
}
然后在构造函数里面写一个私有函数
function animate () {
newPosition+=offset;
list.style.transition = "transform 0.6s";
list.style.transform = "translateY(" + newPosition + "px)";
if (newPosition < -160) {
setTimeout(function () {
newPosition = 0;
list.style.transition = "";
list.style.transform = "translateY(0)";
}, 600);
}
}
我们今天要说的是无缝滚动,到底在哪体现出无缝呢?上面的代码怎么多出了一行list.style.transition?为什么不直接写死在ul上面呢?因为这就是用原生js配合css转换写无缝滚动的关键所在!!
当列表静悄悄地重一开始滑到第五个的时候,这是newPosition刚好等于-160,也就是说ul的translateY为-160,这时候再来那么一下,这么一下照常的会执行这三行:
newPosition+=offset;
list.style.transition = "transform 0.6s";
list.style.transform = "translateY(" + newPosition + "px)";
是的,就在这一下的transition过渡完的那一瞬间,setTimeout可以执行了。没错,就跟前面画的图一样,setTimeout里面的意思就是要让ul回到最起始的位置。
这里需要注意的是,setTimeout的延迟时间和transition的过渡时间必须保持一致,这里就是保持无缝的最关键所在了。
到这里就算是讲完了,其实没多少东西,理解了就很简单。最后祭上代码
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.box{
width: 300px;
height: 40px;
overflow: hidden;
border: 1px solid rebeccapurple;
}
.box>ul{
margin: 0;
padding: 0;
}
.box>ul>li{
list-style-type: none;
width: 300px;
height: 40px;
line-height: 40px;
}
.count{
font-size: 24px;
}
</style>
</head>
<body>
<div class="box">
<ul id="box">
<li>158****546已购买1个月</li>
<li>158****546已购买2个月</li>
<li>158****546已购买3个月</li>
<li>158****546已购买4个月</li>
<li>158****546已购买5个月</li>
<li>158****546已购买1个月</li>
</ul>
</div>
<script src="./slider2.js"></script>
<script>
window.onload = function () {
sliderBox();
}
</script>
</body>
</html>
js
function sliderBox() {
var list = document.getElementById('box'),
newPosition = 0,
offset = -40;
if (!(this instanceof sliderBox)) {
return new sliderBox().init();
}
this.init = function () {
setInterval(animate, 3000);
};
function animate () {
newPosition+=offset;
list.style.transition = "transform 0.6s";
list.style.transform = "translateY(" + newPosition + "px)";
if (newPosition < -160) {
setTimeout(function () {
newPosition = 0;
list.style.transition = "";
list.style.transform = "translateY(0)";
}, 600);
}
}
}
在下文笔拙劣,有什么不清楚或者有出入的地方,烦请斧正!欢迎留言!也希望能给我点赞,鼓励我写出更好的文章。