在大多數的網站裏面首頁都會有一個圖片輪播的效果,而我們開發者要實現這種效果要麼是使用第三方插件,要麼是使用js自己寫函數來實現這種效果,而我自己就是自己寫js來實現這種效果,首先,我們來看一下最終完成的效果:
這個就是最終實現的效果,下面我們來分析一下原理,我們打開一個擁有這種效果的網頁,然後按f12,然後選中那個div,就可以看到下面這種效果:
我們可以看到,這上面有5個div,給它分配一個class叫做slider-panel,繼續看,可以看到這些div擁有一個style屬性,可以看到我們實現輪播效果就是動態的改變div的style屬性,接下來就是介紹源碼了。
首先在html中定義幾個需要輪播的div,如下:
<div class="slider-content">
<div class="slider-panel" style="z-index: 1; display: block;">
<a href="#"><img src="image/3.png" width="520px" height="210px"></a>
</div>
<div class="slider-panel" style="z-index: 0; display: none;">
<a href="#"><img src="image/4.png" width="520px" height="210px"></a>
</div>
<div class="slider-panel" style="z-index: 0; display: none;">
<a href="#"><img src="image/5.png" width="520px" height="210px"></a>
</div>
<div class="slider-panel" style="z-index: 0; display: none;">
<a href="#"><img src="image/6.png" width="520px" height="210px"></a>
</div>
<div class="slider-panel" style="z-index: 0; display: none;">
<a href="#"><img src="image/7.png" width="520px" height="210px"></a>
</div>
</div>
這上面是需要輪播的div,好了,寫完這些,就可以開始js的編寫了:
//代表這裏面有多少個圖片需要輪播
var num = 4;
//代表上面定義id爲slider的div塊的原型對象
function slider(id) {
//保存代表id所指向的元素
this.e = document.getElementById(id);
//獲取class屬性爲slider-content的div
var picDiv = this.e.getElementsByClassName("slider-content");
//獲取class屬性爲slider-panel的div
var picPanels = picDiv[0].getElementsByClassName("slider-panel");
//div圖像
this.picPanels = new Array;
for(var i in picPanels) {
if( typeof picPanels[i] === "object") {
this.picPanels[i] = new div(picPanels[i]);
}
}
//當前顯示的div
this.currentPosition = 0;
//下一個需要顯示的div
this.nextPosition = 1;
}
按照上面的註釋已經說的差不多了,那裏面有這麼一行代碼:
this.picPanels[i] = new div(picPanels[i]);
這裏有一個自定義div對象,就是將class屬性爲slider-panel的div包裝了一下,下面來看下它的定義:
//定義一個對象代表每個圖片div對象
function div(obj) {
//this.e保存div對象
this.e = obj;
//這個對象的style數組
this.style = new Array;
this.style["z-index"] = 0;
this.style["display"] = "none";
this.style["opacity"] = 0;
this.style["background"] = "";
}
這裏的this.style其實就是代表class屬性爲slider-panel這個div裏面的style屬性,我現在只是把它拆開了,爲的是要改變它的值方便,而那裏面的this.e=obj,這個纔是div對象,這個div對象還有一個方法,那就是獲取自己的style屬性,因爲動態改變嘛,所以需要時不時的獲取style屬性然後設置上去:
//獲取div對象的屬性
div.prototype.getStyle = function() {
var s = "z-index: " + this.style["z-index"] + "; display: " + this.style["display"] +
"; ";
if( this.style["z-index"] === 2) {
s += "opacity: " + this.style["opacity"];
}
return s;
}
好了,將這兩個div封裝完整之後,現在開始一個最核心的函數了,那就是slider原型對象的showNext()方法,這個方法用來顯示下一個div:
//顯示下一個
slider.prototype.showNext = function(obj) {
//當前顯示的div對象
var currentObj = obj.picPanels[obj.currentPosition];
//下一個需要顯示的div對象
var nextObj = obj.picPanels[obj.nextPosition];
//設置下一個要顯示的對象的z-index屬性爲2
nextObj.style["z-index"] = 2;
//下一個對象的display屬性
nextObj.style["display"] = "block";
nextObj.style["opacity"] = 0;
//接下來nextObj的opacity的屬性要從0到1切換
for(var i = 0; i < 1000; i++) {
setTimeout(function() {
//增長的步長
var step = 1 / 1000;
nextObj.style["opacity"] += step;
//獲取此時的屬性
var style = nextObj.getStyle();
console.log("style:" + style + "\tcurrentObj-before:" + currentObj.getStyle());
nextObj.e.setAttribute("style", style);
//如果此時這個圖片的opacity屬性切換到了1的動作
if( nextObj.style["opacity"] >= 1) {
currentObj.style["z-index"] = 0;
currentObj.style["display"] = "none";
console.log("currentObj:" + currentObj.getStyle());
//設置當前的屬性
nextObj.style["z-index"] = 1;
console.log("nextObj:" + nextObj.getStyle());
currentObj.e.setAttribute("style", currentObj.getStyle());
//更改遊標的位置
obj.currentPosition = obj.nextPosition;
obj.nextPosition = (++obj.nextPosition) % num === 0 ? num : obj.nextPosition % num;
}
}, 3000);
}
}
這裏面有一個比較難理解的地方,那就是這個函數的形參obj,其實這個obj如果將這個showNext()當作slider對象的成員函數使用就是this,但是這個時候因爲我們這個showNext()必須要一直調用,爲了要實現輪播:
//開始循環切換
slider.prototype.start = function() {
setInterval(this.showNext, 3000, this);
// this.showNext(this);
}
使用這個setInterval()函數之後這個showNext()函數就不屬於slider這個對象的了,所以需要先保存this
obj.nextPosition = (++obj.nextPosition) % num === 0 ? num : obj.nextPosition % num;
這一行代碼屬於計算下一位置,便於取出下一要滑動的div對象,這裏面還使用了setTimeout函數,這個函數是延時函數,如果不使用這個函數的話,就體現不出來改變的效果了。下面開始調用:
//當頁面加載完成的時候創建對象,否則document未創建完成
window.onload = function() {
div = new slider("slider");
//設置第一個圖像的內容
var firstDiv = div.picPanels[0];
firstDiv.style["z-index"] = 1;
firstDiv.style["display"] = "block";
//圖片開始切換
div.start();
}
再補充一點,如果直接按照上面的運行會出現一些不想要的效果,我們得需要設置單獨寫一些css屬性:
#slider .slider-content {
min-width: 520px;
height: 210px;
position: relative;
overflow: hidden;
}
#slider .slider-panel {
position: absolute;
left : 0;
top: 0;
width: 100%;
height: 100%;
display: none;
}