怎樣用原生js配合css的transition寫個無縫滾動

阿9發表於2018-07-23

之所以想要寫原生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是一樣的(哈哈哈,就是說明一下它倆是一樣的)上圖!!啊哈哈哈哈,將就看一下,我畫了好久的。這裡為了節約空間就橫著放了,下面的例子的滾動是向上走的。

怎樣用原生js配合css的transition寫個無縫滾動

當焦點位於圖片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);
        }
    }
}
複製程式碼

在下文筆拙劣,有什麼不清楚或者有出入的地方,煩請斧正!歡迎留言!也希望能給我點贊,鼓勵我寫出更好的文章。


相關文章