一步一步教你写淡入淡出带注释的图片轮播插件(一)
时间:2010-10-10 来源:岑安
前几天在blueIdea上看到一个淡入淡出的带注释的图片轮播效果http://bbs.blueidea.com/thread-2911266-1-1.html看了帖子作者的代码,虽然效果达到了,但是有几个地方本人有不同的看法:
1.那位作者的思路是隐藏掉真正的图片列表,而新建一个div,通过不断push当前图片到那个div的innerHTML里的方式来做一个一个交替变化。思路虽然有些新意,但是从目标效果的运行逻辑来看,通过改变列表元素的z-index值来实现交替变换其实更符合这个效果逻辑的初衷。
2.那位作者虽然对代码做了一定程度的封装,但封装的还是不很好,在效果的可配置上做的不很好,于是乎,这只能是一个效果,而不能作为一个可配置的插件。
(ps:以上观点纯属就事论事,无任何怀疑此作者功力的意思。且不同人有不同看法。纯属个人观点)
所以,我自己也抽空写了个类似的效果,做了一定程度的封装,虽然也只能勉强算个轻量级原生小插件吧,但还是分享出来,并做一步一步的教程,希望能给有需要的朋友一些帮助吧。先上个最终的效果图吧:
好了,Let's go!开始我们的第一部分吧!
第一部分我们要达到的目标有:
1.建立一个大的框架,实现变换的逻辑,同时建立良好的代码结构,为以后的功能扩展打好基础。(好的开始是成功的一半!)
2.第一部分要实现的效果为图片自动切换(仅仅是这一个功能)。
首先要有清晰地思路,要实现这一个效果,我们一定是调用一个初始化函数init()-->init()中开始变换第一张图片到下一张,不妨暂定这个功能函数为pos()-->要实现自动交替变换,那么肯定需要一个自动变换的功能函数auto()-->auto()中自动变换应该有两个方向,向前和向后,那么这个功能我们也可以通过一个函数来实现,暂定move()-->move()中是指定向上或向下一张变换,那么就可以回归到我们的变换函数pos()中!
那么,我们就建立了一套完整可行的逻辑体系。根据以上逻辑,我们用代码结构来表示如下:
var Hongru={}; Hongru.fader = function(){ return{ init:function(options){ //options参数:id(必选):图片列表父标签id;auto(可选):自动运行时间;index(可选):开始的运行的图片序号 this.pos(this.index); //变换函数 }, auto:function(){ setInterval(new Function('Hongru.fader.move(1)'),this.a*1000); }, move:function(i){//参数i有两种选择,1和-1,1代表运行到下一张,-1代表运行到上一张 this.pos(m); //变换到上一张或下一张 }, pos:function(i){ this.auto(); //自动运行 } } }();
以上只是我个人的编码习惯:把功能块都写在一个闭包里,减少命名冲突,避免全局变量污染。(但是这样会有个问题,所有函数都在闭包里,很可能会导致ie内存泄露,所以还有另外种更好的方式:只把初始化函数写入闭包,其他功能通过原型内建。这样同样可以避免命名冲突和全局变量污染,又同时减轻了内存压力。这个优化方案将在下一部分一起说明)
好了,大的框架出来了,我们其实就成功了一半了,以下再根据每个模块具体的功能充实函数。由于dom选择器使我们最常使用的功能,所以这里预先定义了两个全局函数
function H$(id){return document.getElementById(id)} function H$$(c,p){return p.getElementsByTagName(c)}
相信大家都懂。
下面是每个模块函数的拆解:
init模块:
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:
auto:function(){ this.li.a = setInterval(new Function('Hongru.fader.move(1)'),this.a*1000); },
move:
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:
pos:function(i){ clearInterval(this.li.a); this.z++; this.li[i].style.zIndex = this.z; //每次让下一张图片z-index加一 this.cur = i; //绑定当前显示图片的正确序号 this.auto(); //自动运行 }
好了,总的源码是这样的:
<!Doctype html> <html> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8" /> <title>step1</title> <mce:style type="text/css"><!-- #fader{position:relative;overflow:hidden;width:500px} #fader li{position:absolute;left:0;top:0;} ul,li{list-style:none;margin:0;padding:0} img{display:block;} --></mce:style><style type="text/css" _mce_bogus="1"><!-- #fader{position:relative;overflow:hidden;width:500px} #fader li{position:absolute;left:0;top:0;} ul,li{list-style:none;margin:0;padding:0} img{display:block;} --></style> <script type="text/javascript"><!-- var Hongru={}; function H$(id){return document.getElementById(id)} function H$$(c,p){return p.getElementsByTagName(c)} Hongru.fader = function(){ return{ 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('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(); //自动运行 } } }(); // --></script> </head> <body> <div id="fader"> <ul> <li><img src="http://images.cnblogs.com/cnblogs_com/hongru/264552/o_1.jpg" _mce_src="http://www.cnblogs.com/hongru/1.jpg" alt="我是图片一" /></li> <li><img src="http://images.cnblogs.com/cnblogs_com/hongru/264552/o_2.jpg" _mce_src="http://www.cnblogs.com/hongru/2.jpg" alt="哈哈,图片二" /></li> <li><img src="http://images.cnblogs.com/cnblogs_com/hongru/264552/o_3.jpg" _mce_src="http://www.cnblogs.com/hongru/3.jpg" alt="这是图片三" /></li> <li><img src="http://images.cnblogs.com/cnblogs_com/hongru/264552/o_4.jpg" _mce_src="http://www.cnblogs.com/hongru/4.jpg" alt="哈哈,图片四" /></li> <li><img src="http://images.cnblogs.com/cnblogs_com/hongru/264552/o_5.jpg" _mce_src="http://www.cnblogs.com/hongru/5.jpg" alt="图片五来咯" /></li> </ul> </div> <script type="text/javascript"><!-- Hongru.fader.init({ id:'fader' }); // --></script> </body> </html>
恩,这一部分到此结束吧,下一部分将增加淡入淡出效果和刚才提到了尽量规避闭包引起的内存泄露的优化方案!