之所以想要寫原生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);}}
}
復制代碼
在下文筆拙劣,有什么不清楚或者有出入的地方,煩請斧正!歡迎留言!也希望能給我點贊,鼓勵我寫出更好的文章。