輪播圖就是讓圖片每隔幾秒自動滑動,達到圖片輪流播放的效果。輪播圖從效果來說有滑動式的也有漸入式的,滑動式的輪播圖就是圖片從左向右滑入的效果,漸入式的輪播圖就是圖片根據透明度漸漸顯示的效果,這里說的是實現第一種效果的方法。
原理
相同大小的圖片並成一列,但只顯示其中一張圖片,其余的隱藏,通過修改left值來改變顯示的圖片。
點擊查看效果
html部分
nav為總容器,第一個ul列表#index為小圓點列表,鼠標覆蓋哪個小圓點就顯現第幾張圖片,on是一個給小圓點添加背景顏色屬性的類;第二個ul列表#img為圖片列表。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Carousel Figure</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<!--從左向右滑動-->
<nav>
<ul id="index">
<li class="on"></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
<ul id="img">
<li><img src="../images/img1.jpg" alt="img1"></li>
<li><img src="../images/img2.jpg" alt="img2"></li>
<li><img src="../images/img3.jpg" alt="img3"></li>
<li><img src="../images/img4.jpg" alt="img4"></li>
<li><img src="../images/img5.jpg" alt="img5"></li>
</ul>
</nav>
<script src="script.js"></script>
</body>
</html>
css部分
圖片尺寸均為720*405,這里需要注意以下幾點:
-
ul#img列表相對於nav是絕對定位的,#img的長度必須設置為所有圖片的總寬度,這樣圖片才可以並列一排顯示;
-
總容器nav的寬度必須設置為圖片的寬度720px,即只能顯示一張圖片,超出寬度的部分隱藏,即overflow: hidden;
-
小圓點列表應該在圖片列表上面顯示,故設置#img的z-index:-1;
-
小圓點列表是由一系列的li通過改變邊框樣式構成,故只需改變背景顏色即可達到移動小圓點的效果。
*{
margin:0;
padding:0;
}
nav{
width: 720px;
height: 405px;
margin:20px auto;
overflow: hidden;
position: relative;
}
#index{
position: absolute;
left:320px;
bottom: 20px;
}
#index li{
width:8px;
height: 8px;
border: solid 1px gray;
border-radius: 100%;
background-color: #eee;
display: inline-block;
}
#img{
width: 3600px;/*不給寬高無法移動*/
height: 405px;
position: absolute;/*不定義absolute,js無法設置left和top*/
z-index: -1;
}
#img li{
width: 720px;
height: 405px;
float: left;
}
#index .on{
background-color: black;
}
JS部分
圖片移動函數moveElement()
moveElement函數需要獲取圖片現在的位置以及目標位置並計算它們之間的差距進行移動,可以用offsetLeft和offsetTop獲取圖片現在的位置。圖片移動時“划過”的效果是將距離分成好10次進行移動,即利用setTimeOut函數,然而為了防止鼠標懸停,需調用clearTimeout()函數,代碼如下:
function moveElement(ele,x_final,y_final,interval){//ele為元素對象
var x_pos=ele.offsetLeft;
var y_pos=ele.offsetTop;
var dist=0;
if(ele.movement){//防止懸停
clearTimeout(ele.movement);
}
if(x_pos==x_final&&y_pos==y_final){//先判斷是否需要移動
return;
}
dist=Math.ceil(Math.abs(x_final-x_pos)/10);//分10次移動完成
x_pos = x_pos<x_final ? x_pos+dist : x_pos-dist;
dist=Math.ceil(Math.abs(y_final-y_pos)/10);//分10次移動完成
y_pos = y_pos<y_final ? y_pos+dist : y_pos-dist;
ele.style.left=x_pos+'px';
ele.style.top=y_pos+'px';
ele.movement=setTimeout(function(){//分10次移動,自調用10次
moveElement(ele,x_final,y_final,interval);
},interval)
}
小圓點移動函數moveIndex()
移動小圓點的實質是移動設置的背景顏色的類on,原理是先判斷哪個li上有背景顏色,有則去掉,讓所有的li都沒有背景,然后在對當前的li添加背景。
function moveIndex(list,num){//移動小圓點
for(var i=0;i<list.length;i++){
if(list[i].className=='on'){//清除li的背景樣式
list[i].className='';
}
}
list[num].className='on';
}
圖片自動輪播
將以下代碼直接寫在window.onload中即可。
這里需要定義一個變量index,表示移動到第index(0~n-1,n為li的個數)張圖片。
var img=document.getElementById('img');
var list=document.getElementById('index').getElementsByTagName('li');
var index=0;//這里定義index是變量,不是屬性
var nextMove=function(){//一直向右移動,最后一個之后返回
index+=1;
if(index>=list.length){
index=0;
}
moveIndex(list,index);
moveElement(img,-720*index,0,20);
};
圖片的自動輪播需要用到setInterval()函數,讓程序每隔幾秒自動調用nextMove()函數:
var play=function(){
timer=setInterval(function(){
nextMove();
},2500);
};
鼠標覆蓋小圓點效果
要實現鼠標覆蓋哪個小圓點,就呈現出對應的圖片這一效果,需要知道鼠標覆蓋的是哪個小圓點,這里給每個li都添加一個自定的屬性index,使該屬性的值為對應的小圓點的序號i(0~n-1,n為li的個數),這樣每次鼠標覆蓋時只需獲取index屬性的值即可知道鼠標覆蓋的是哪個小圓點。注意,該index屬性和變量index沒有絲毫的關系,只有相同的名字。
for(var i=0;i<list.length;i++){//鼠標覆蓋上哪個小圓圈,圖片就移動到哪個小圓圈,並停止
list[i].index=i;//這里是設置index屬性,和index變量沒有任何聯系
list[i].onmouseover= function () {
var clickIndex=parseInt(this.index);
moveElement(img,-720*clickIndex,0,20);
index=clickIndex;
moveIndex(list,index);
clearInterval(timer);
};
list[i].onmouseout= function () {//移開后繼續輪播
play();
};
}
總結
輪播圖的實現並不復雜,主要在於將圖片的移動行為和小圓點的移動行為分開,這樣就比較容易實現。這個輪播圖其實還是有點問題的,從最后一幅圖滑向第一個時滑動的距離較長,其實也很好解決,將滑動的方式改一下,這里是根據-720*index來計算最終的left值,而index是將圖片的移動和小圓點的移動綁到一起,將滑動方式改成現在的offsetLeft+(-720),圖片的移動就可以與index值無關,然后在html文件增加一幅圖片:
<li><img src="../images/img1.jpg" alt="img1"></li>
<li><img src="../images/img2.jpg" alt="img2"></li>
<li><img src="../images/img3.jpg" alt="img3"></li>
<li><img src="../images/img4.jpg" alt="img4"></li>
<li><img src="../images/img5.jpg" alt="img5"></li>
<li><img src="../images/img1.jpg" alt="img1"></li>
然后在滑到最后一幅圖片時,迅速的將偏移量賦值0,變成第一幅,兩幅圖一樣,無法分辨其中變化,即可達到無縫連接。
if(x_pos==-3600){
ele.style.left='0';
ele.style.top='0';
}else{
ele.style.left=x_pos+'px';
ele.style.top=y_pos+'px';
}