DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> JavaScript入門知識 >> 關於JavaScript >> 一步一步教你寫淡入淡出帶注釋的圖片輪播插件(二)
一步一步教你寫淡入淡出帶注釋的圖片輪播插件(二)
編輯:關於JavaScript     
接上一篇,現在進行第二部分。
  開始之前,還是說說前文提到的關於把所有函數都寫在一個閉包內的優化問題。前文也提到了,因為我們在初始化的時候要調用的只是init,所以可以只把init寫入閉包,其他功能函數作為init的原型繼承方法來調用。所以前文的代碼其實可以這樣改寫:
復制代碼 代碼如下:
var Hongru={};
function H$(id){return document.getElementById(id)}
function H$$(c,p){return p.getElementsByTagName(c)}
Hongru.fader = function(){
function init(options){ //options參數:id(必選):圖片列表父標簽id;auto(可選):自動運行時間;index(可選):開始的運行的圖片序號
var wp = H$(options.id), // 獲取圖片列表父元素
ul = H$$('ul',wp)[0], // 獲取
li = this.li = H$$('li',ul);
this.a = options.auto?options.auto:2; //自動運行間隔
this.index = options.position?options.position:0; //開始運行的圖片序號(從0開始)
this.l = li.length;
this.cur = this.z = 0; //當前顯示的圖片序號&&z-index變量
this.pos(this.index); //變換函數
}
init.prototype = {
auto:function(){
this.li.a = setInterval(new Function('Hongru.fader.move(1)'),this.a*1000);
},
move:function(i){//參數i有兩種選擇,1和-1,1代表運行到下一張,-1代表運行到上一張
var n = this.cur+i;
var m = i==1?n==this.l?0:n:n<0?this.l-1:n; //下一張或上一張的序號(注意三元選擇符的運用)
this.pos(m); //變換到上一張或下一張
},
pos:function(i){
clearInterval(this.li.a);
this.z++;
this.li[i].style.zIndex = this.z; //每次讓下一張圖片z-index加一
this.cur = i; //綁定當前顯示圖片的正確序號
this.auto(); //自動運行
}
}
return {init:init}
}();

但是這樣其實是有問題的,不知道大家發現沒有,如果這樣改寫的話,在auto函數裡就不能再調用‘Hongru.fader.move()'了,這是沒定義的,那有人會說,既然是init的原型繼承,那就調用'Hongru.fader.init.move()'不就對了嗎?其實也不對,我在以前的文章中就討論過這個問題http://www.cnblogs.com/hongru/archive/2010/10/09/1846636.html;init在沒有實例化之前是訪問不到它的prototype的,所以我們在這樣做的時候要注意兩個問題,
  一個是初始化的時候要用new關鍵字對init實例化。
  另外一個是在代碼內部調用它的原型方法時也要通過我們實例化後的對象來調用,舉個例子,比如我們對上面的代碼初始化的時候應該是這樣的
復制代碼 代碼如下:
var newFader = new Hongru.fader.init({ //這個new很重要
id:'fader'
});

如果我們在代碼裡要調用init的方法要通過我們新建的實例化對象newFader來調用,比如在上面的auto函數裡要調用init的move方法的話,就直接調用'newFader.move()',這樣才行。
  可是這樣還有個小問題,就是必須要保證實例化的變量名和代碼中調用的一致,那麼如果我改了我的初始化對象的名字,比如用newFader1,那麼我還得去改源碼,這樣肯定是不行的,所以有個小技巧,就是在init裡面多傳一個參數,自己在做初始化的時候讓變量名和參數一致,然後在源碼裡我們通過參數來調用。這樣問題就圓滿的解決了。
(ps:代碼裡之所以使用new Function的原因也是因為這樣能沖破作用域鏈,這也是保證我們能這樣架構我們代碼的條件之一。)
綜上:之前的代碼應該這樣優化:
復制代碼 代碼如下:
var Hongru={};
function H$(id){return document.getElementById(id)}
function H$$(c,p){return p.getElementsByTagName(c)}
Hongru.fader = function(){
function init(anthor,options){this.anthor=anthor; this.init(options);}
init.prototype = {
init:function(options){ //options參數:id(必選):圖片列表父標簽id;auto(可選):自動運行時間;index(可選):開始的運行的圖片序號
var wp = H$(options.id), // 獲取圖片列表父元素
ul = H$$('ul',wp)[0], // 獲取
li = this.li = H$$('li',ul);
this.a = options.auto?options.auto:2; //自動運行間隔
this.index = options.position?options.position:0; //開始運行的圖片序號(從0開始)
this.l = li.length;
this.cur = this.z = 0; //當前顯示的圖片序號&&z-index變量
this.pos(this.index); //變換函數
},
auto:function(){
this.li.a = setInterval(new Function(this.anthor+'.move(1)'),this.a*1000);
},
move:function(i){//參數i有兩種選擇,1和-1,1代表運行到下一張,-1代表運行到上一張
var n = this.cur+i;
var m = i==1?n==this.l?0:n:n<0?this.l-1:n; //下一張或上一張的序號(注意三元選擇符的運用)
this.pos(m); //變換到上一張或下一張
},
pos:function(i){
clearInterval(this.li.a);
this.z++;
this.li[i].style.zIndex = this.z; //每次讓下一張圖片z-index加一
this.cur = i; //綁定當前顯示圖片的正確序號
this.auto(); //自動運行
}
}
return {init:init}
}();

初始化時應該這樣:
復制代碼 代碼如下:
var fader = new Hongru.fader.init('fader',{ //保證第一個參數和變量名一致
id:'fader'
});

好了,代碼的優化方案到此結束。下面是第二部分效果的實現:淡入淡出的效果
其實有了上面良好的代碼結構和邏輯的話,加入淡入淡出效果是比較容易的,思路很簡單,在變化之前讓圖片透明,然後通過計時器讓透明度漸漸增加。只不過這裡面有幾個邊界的判斷是比較重要的。同時透明度改變在ie和非ie下要注意用不同的css屬性。
  核心代碼的改動就下面兩段,一個是增加了透明度漸變函數fade(),另一個是在pos()裡面事先要先把圖片透明-->然後開始執行fade()
pos()裡增加一個代碼段:
復制代碼 代碼如下:
if(this.li[i].o>=100){ //在圖片淡入之前先把圖片透明度置為透明
this.li[i].o = 0;
this.li[i].style.opacity = 0;
this.li[i].style.filter = 'alpha(opacity=0)';
}
this.li[i].f = setInterval(new Function(this.anthor+'.fade('+i+')'),20);

然後加一個功能函數fade()
復制代碼 代碼如下:
fade:function(i){
if(this.li[i].o>=100){
clearInterval(this.li[i].f); //如果透明度變化完畢,清除計時器
if(!this.li.a){ //確保所有計時器都清除掉之後再開始自動運行。要不然會導致有控制器時點擊過快的話,計時器沒來得及清除就開始下一次變化,功能就亂了
this.auto();
}
}
else{ //透明度變化
this.li[i].o+=5;
this.li[i].style.opacity = this.li[i].o/100;
this.li[i].style.filter = 'alpha(opacity='+this.li[i].o+')';
}
}

好了,就這麼簡單。不過還有一點要記住就是在pos()調用的最初一定要記得清除上次的計時器!!
下面再把整個的源碼都貼一遍吧:
復制代碼 代碼如下:
var Hongru={};
function H$(id){return document.getElementById(id)}
function H$$(c,p){return p.getElementsByTagName(c)}
Hongru.fader = function(){
function init(anthor,options){this.anthor=anthor; this.init(options);}
init.prototype = {
init:function(options){ //options參數:id(必選):圖片列表父標簽id;auto(可選):自動運行時間;index(可選):開始的運行的圖片序號
var wp = H$(options.id), // 獲取圖片列表父元素
ul = H$$('ul',wp)[0], // 獲取
li = this.li = H$$('li',ul);
this.a = options.auto?options.auto:2; //自動運行間隔
this.index = options.position?options.position:0; //開始運行的圖片序號(從0開始)
this.l = li.length;
this.cur = this.z = 0; //當前顯示的圖片序號&&z-index變量
/* ==加入淡入淡出功能 ==*/
for(var i=0;i<this.l;i++){
this.li[i].o = 100; //為每一個圖片都設置一個透明度變化量
this.li[i].style.opacity = this.li[i].o/100; //非IE用opacity即可
this.li[i].style.filter = 'alpha(opacity='+this.li[i].o+')'; //IE用濾鏡
}
this.pos(this.index); //變換函數
},
auto:function(){
this.li.a = setInterval(new Function(this.anthor+'.move(1)'),this.a*1000);
},
move:function(i){//參數i有兩種選擇,1和-1,1代表運行到下一張,-1代表運行到上一張
var n = this.cur+i;
var m = i==1?n==this.l?0:n:n<0?this.l-1:n; //下一張或上一張的序號(注意三元選擇符的運用)
this.pos(m); //變換到上一張或下一張
},
pos:function(i){
clearInterval(this.li.a); //清除自動變換計時器
clearInterval(this.li[i].f); //清除淡入淡出效果計時器
this.z++;
this.li[i].style.zIndex = this.z; //每次讓下一張圖片z-index加一
this.cur = i; //綁定當前顯示圖片的正確序號
this.li.a = false; //做一個標記,下面要用到,表示清除計時器已經完成
//this.auto(); //自動運行
if(this.li[i].o>=100){ //在圖片淡入之前先把圖片透明度置為透明
this.li[i].o = 0;
this.li[i].style.opacity = 0;
this.li[i].style.filter = 'alpha(opacity=0)';
}
this.li[i].f = setInterval(new Function(this.anthor+'.fade('+i+')'),20);
},
fade:function(i){
if(this.li[i].o>=100){
clearInterval(this.li[i].f); //如果透明度變化完畢,清除計時器
if(!this.li.a){ //確保所有計時器都清除掉之後再開始自動運行。要不然會導致有控制器時點擊過快的話,計時器沒來得及清除就開始下一次變化,功能就亂了
this.auto();
}
}
else{
this.li[i].o+=5;
this.li[i].style.opacity = this.li[i].o/100;
this.li[i].style.filter = 'alpha(opacity='+this.li[i].o+')';
}
}
}
return {init:init}
}();

大家要注意我寫的注釋,有些地方是比較關鍵的。
再看看運行效果吧:

[Ctrl+A 全選 注:如需引入外部Js需刷新才能執行]
可能有人注意到了,這裡的淡入淡出只是個頭銜,其實只有淡入效果,不過不礙事,效果其實和有淡出基本一樣,而且就算要淡出功能也僅僅需要改兩句話。呵呵
這一部分到此結束,下一部分會加入控制器。
XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved