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