1. 程式人生 > >JS實現圖片無縫滾動效果

JS實現圖片無縫滾動效果

首先,藉助一張草圖來簡單說明一下往左移動的做法(往右相同)。
這裡寫圖片描述
如上圖所示,圖片的無縫滾動原理其實是把滾動的圖片複製成兩份並聯排列,當滾動完一次後就把圖片扯回到起點,重新滾動。這裡的往左運動把圖片扯回起點的臨界點是offsetLeft的絕對值大於offsetWidth/2的絕對值。

接著,我們再來看看具體實現的程式碼:
第一步:簡單的佈局,這裡以外層的div為相對物設定相對定位並設定超出隱藏,再給裡面的ul設定絕對定位,然後通過JS控制left和top的值來實現圖片的移動。
要注意的是:無縫滾動圖如果不設定margin和padding值為0會出現bug,圖片銜接缺畫素,兩段圖片移動完後會出現卡跳現象。新聞滾動如果不設定margin和padding為0,則會出現反向加速運動的bug。估計bug是因為所有元素間自動存在間隙,而設定的運動畫素和內邊距padding有關?會不會呢?誰知道。。。。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style type="text/css">
            *{margin: 0;padding: 0;}
            #box{width: 800px;height: 150px;margin: 100px auto;position: relative;background: red;overflow: hidden
;}
#box ul{position: absolute;left: 21px;top: 17px;} #box ul li{float: left;width: 190px;height: 150px;list-style: none;}
</style> </head> <body> <a href="javascript:;">向左走</a> <a href="javascript:;">向右走</a> <div
id="box">
<ul> <li><img src="../img/images/a1.jpeg"/></li> <li><img src="../img/images/a2.jpeg"/></li> <li><img src="../img/images/a3.jpeg"/></li> <li><img src="../img/images/a4.jpeg"/></li> </ul> </div> </body> </html>

第二步:根據標籤名和ID名獲取即將要用到的元素。這裡也有一個隱藏的知識點:通過標籤名獲取元素,返回的是物件的集合(陣列),[<p#pp.aa>,<p#ppp.aa>,<p#pppp.aa>],就是<標籤名id名類名>這樣的一個集合,後面加[0]返回的就是第一個物件,就像獲取陣列內的元素一樣,如果不加[0]是就出現了錯誤。或者可以改成通過Id名獲取元素,這樣就返回的第一個物件,<p id="pp" class="aa"></p>是這樣的,不過不返回文字內容

var oDiv=document.getElementById('box');

var oUl=oDiv.getElementsByTagName('ul')[0];

var aLi=oUl.getElementsByTagName('li');

第三步:把ul的內容加長到2倍,寫一個函式,left值減去2px,先讓函式執行一次,避免出現載入完頁面後先出現停頓的現象,然後定義一個定時器,每30毫秒執行一次,實現圖片滾動效果。

oUl.innerHTML+=oUl.innerHTML;

function move(){

    oUl.style.left=oUl.offsetLeft-2+'px';

}
//先執行一次函式
move();
//設定一個短時定時器,讓圖片運動看起來流暢
var timer=setInterval(move,30);

第四步:計算ul的總長度:獲取一個li的寬度(不要單位)*li的數量+單位。然後寫兩個條件語句,判斷滾動是否到達臨界點,如果到達,就執行相對應的操作。

oUl.style.width=aLi[0].offsetWidth*aLi.length+'px';
function move(){
    //這裡的移動,往左left為負,往右為正
    //往左的移動,判斷ul的left值,如果小於負長度的一半,說明內容的第二段已經移動完,則left要歸零重新移動
    if(oUl.offsetLeft<-oUl.offsetWidth/2){
        oUl.style.left='0';
    }
    //往右的移動,判斷ul的left值,如果大於0,說明內容的第二段已經移動完,則left要回到負長度的一半重新移動,則left要重新設定為負長度的一半
    if(oUl.offsetLeft>0){
        oUl.style.left=-oUl.offsetWidth/2+'px';
    }
    oUl.style.left=oUl.offsetLeft-2+'px';
}

第五步:設定一個變數,賦值為每次滾動的畫素,並且把常量2改為speed;如果變更滾動方向時,只需改變變數speed的符號即可。

var speed=2;

oUl.style.left=oUl.offsetLeft+speed+'px';

//滑鼠點選事件,speed為負數,往左走
document.getElementsByTagName('a')[0].onclick=function(){
    speed=-2;
}
//滑鼠點選事件,speed為正數,往右走
document.getElementsByTagName('a')[1].onclick=function(){
    speed=2;
}

第六步:最後加上兩個滑鼠事件,效果就OK啦。

//滑鼠經過事件,關閉定時器,圖片停止移動
oDiv.onmousemove=function(){
    clearInterval(timer);
}
//滑鼠離開事件,重新開啟定時器
oDiv.onmouseout=function(){
    timer=setInterval(move,30);
}

雖然已經是完成了這麼一個效果,但是還有一些bug是沒有解決的,等以後學了更加知識再慢慢修正吧。