一步一步教你写淡入淡出带注释的图片轮播插件(二)

接上一篇,现在进行第二部分。
  开始之前,还是说说前文提到的关于把所有函数都写在一个闭包内的优化问题。前文也提到了,因为我们在初始化的时候要调用的只是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}
}();

大家要注意我写的注释,有些地方是比较关键的。
再看看运行效果吧:

step2

=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需刷新才能执行]

可能有人注意到了,这里的淡入淡出只是个头衔,其实只有淡入效果,不过不碍事,效果其实和有淡出基本一样,而且就算要淡出功能也仅仅需要改两句话。呵呵
这一部分到此结束,下一部分会加入控制器。

(0)

相关推荐

  • 一步一步教你写带图片注释的淡入淡出插件(三)

    其实凭借着之前良好的代码结构,加入控制器很简单(^_^这也就是为什么我说刚开始的架构的代码结构很重要!) 先说一下加入控制器的思路: 根据轮播元素的个数为每一个元素添加一个对应的控制按钮,(这里我直接用a标签来做,考虑语义的话可以用ul或ol),考虑到书写样式的方便可以先create一个控制器父标签,然后依次把每个控制按钮append到控制器父标签,再把父标签append到我们的轮播模块中就ok了.然后再为对应的元素添加上对应的css样式即可 好了,说完思路,咱们动手开始,控制器的绘制应该在in

  • 一步一步教你写带图片注释的淡入淡出插件(四)

    不出意外的话,这应该是这个系列的最后一部分了. 第三部分的效果已经基本上满足大部分的需求了.所以这一部分呢,只能算是加分项.废话不多说了,还是继续博文吧. 其实带背景半透明的备注的轮播效果也是网上一抓一大把,163,qq,taobao等等,仔细找找应该都能看到类似的效果.添加文本其实和前一文的添加控制器的方法差不多.无非也就是再append一个元素,在里面显示文本即可. 复制代码 代码如下: /* -- 显示备注 --*/ var alt = this.alt = document.create

  • 一步一步教你写淡入淡出带注释的图片轮播插件(二)

    接上一篇,现在进行第二部分. 开始之前,还是说说前文提到的关于把所有函数都写在一个闭包内的优化问题.前文也提到了,因为我们在初始化的时候要调用的只是init,所以可以只把init写入闭包,其他功能函数作为init的原型继承方法来调用.所以前文的代码其实可以这样改写: 复制代码 代码如下: var Hongru={}; function H$(id){return document.getElementById(id)} function H$$(c,p){return p.getElements

  • js淡入淡出的图片轮播效果代码分享

    本文实例讲述了淡入淡出的js图片轮播效果代码.分享给大家供大家参考.具体如下: 运行效果图:----------------------查看效果----------------------- 小提示:浏览器中如果不能正常运行,可以尝试切换浏览模式. 为大家分享的js图片轮播效果代码如下 <html> <head> <title>js图片轮播效果代码</title> <style type="text/css"> table i

  • 手把手教你用ViewPager自定义实现Banner轮播

    欢迎大家关注Android开源网络框架NoHttp:https://github.com/yanzhenjie/NoHttp 我们在实际开发中,很多App都会在做一个广告轮播器(可能是图片,可能是其他View),很多同学都是使用别人封装好的或者直接使用ViewPager自己来改,但是有人可能并不理解里面的原理,或者有人遇到了手势滑动冲突.我们今天就用150行代码实现一自定义的广告轮播器并不干扰原来View滑动事件. 本例代码源码及Demo传送门 效果演示 需求分析.解决方案 轮播器最重要的几个特

  • 教你一步步用jQyery实现轮播器

    实现原理 如图,试想一下,若是将<ul>的width属性值设置的很宽,直到可以装下你所有的图片,而每一个图片又用<li>包着并且设置了左浮动. 那么当我们向左移动ul的时候并且移动的距离为<li>的宽度,第二个<li>不就被移动到了<div>的窗口,这样一来图片不就被一张一张显示出来了吗? 接下来我们在设置<div>的属性overflow:hidden,那么<div>窗口以外的图片不显示,只显示移动到当前窗口的图片,是不是

  • javascript原生封装一个淡入淡出效果的函数测试实例代码

    说到js的渐变显示与消失,多数朋友会想到JQuery里面的fadeIn().fadeOut()或fadeToggle().但如果仅仅是为了引入这样的一个效果,而去调用了庞大JQuery库?或者说我通过用原生js实现一些函数来提高自己~ 所以,我简单的研究了一下纯js代码写淡入淡出的效果. 如果出现错误,请在评论中指出,我也好自己纠正自己的错误 (一)FadeIn淡入函数 淡入淡出的效果,其实就是一个setInterval(),加上循环的DOM操作,通过改变element对象节点的透明度,即可实现

  • jQuery实现淡入淡出效果

    用jQuery完成淡入淡出效果前,我们先来认识几个代码: 淡入 fadeIn([ speed , [easing] , [fn] ]),参数都可不写 淡出 fadeOut([ speed , [easing] , [fn] ]),参数都可不写 淡入淡出切换 fadeToggle([ speed , [easing] , [fn] ]),参数都可不写 修改透明度 fadeTo([ [speed] , opacity , [easing] , [fn] ]),注意,这里速度和透明度一定要写 其中 s

  • 一步一步教你网站同步镜像(转载)

    1.介绍 现在的网站随着访问量的增加,单一服务器无法承担巨大的访问量,有没有什么方便快捷的方式解决这个问题呢,答案是"有"!比如建立服务器群,进行均衡负载. 但是如果要解决像电信网通这样的互访问题(中国网民的悲哀..),这个解决办法就无能为了了! 要解决这个问题最方便快捷的方式就是建立镜像网站!由访问者自己选择适合自己网络的速度最快的网站!这样即可以解决线路问题,又可以解决访问量问题! 2.网站同步的数据分类 网站数据基本分为两类: 一类是文件,比如HTML,ASP,PHP等网页文件,

  • 教你一步一步在linux中正确的安装Xcache加速php

    首先,强烈吐槽,百度上的教程,都左复制右复制的,乱七八糟,缺东缺西的.借此微凉大大我提供我苦心整理好的教程.以便各位小菜能顺利的使用Xcache加速php,如果看完了,也操作了,还是失败了的话,请联系微凉大大的QQ 496928838,微凉大大也想看看你是如何一步一步都装不上. #第一步,下载Xcache wget http://xcache.lighttpd.net/pub/Releases/3.1.0/xcache-3.1.0.tar.gz #第一步非常简单,如果你下载不了就是人品问题. #

随机推荐