怎样用原生js配合css的transition写个无缝滚动

520 阅读4分钟

之所以想要写原生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);
        }
    }
}

在下文笔拙劣,有什么不清楚或者有出入的地方,烦请斧正!欢迎留言!也希望能给我点赞,鼓励我写出更好的文章。