SlideView 图片滑动(扩展收缩)展示效果

it2025-03-15  22

滑动展示效果主要用在图片或信息的滑动展示,也可以设置一下做成简单的口风琴(Accordion)效果。这个其实就是以前写的图片滑动展示效果的改进版,那是我第一篇比较受关注的文章,是时候整理一下了。有如下特色:1,有四种方向模式选择;2,结合tween算法实现多种滑动效果;3,能自动根据滑动元素计算展示尺寸;4,也可自定义展示或收缩尺寸;5,可扩展自动切换功能;6,可扩展滑动提示功能。兼容:ie6/7/8, firefox 3.6.8, opera 10.51, safari 4.0.5, chrome 5.0

效果预览

0 0 1 1 2 2 3 3 4 4 模式: 左边右边 默认索引: 无01234 尺寸: 按元素尺寸展示占一半展示200px收缩占十分一收缩80px 关闭: 自动不自动 速度: 默认快速慢速 tween: 默认反弹 图片滑动展示效果: 内裤蛋糕 神秘浪漫的内裤蛋糕礼盒 内裤蛋糕 送给最亲密的TA~~ 内裤蛋糕 超SWEET~~打开漂亮的礼品盒,甜蜜可爱的蛋糕呈现眼前 内裤蛋糕 好Q哦!慢慢解开丝带,竟然是一条条漂亮的内裤 内裤蛋糕 超级SWEET又脸红耶!!! 仿口风琴(Accordion)效果: 图片放大效果 这个效果也叫放大镜效果,最早好像在ppg出现的,之后就有了很多仿制品出来了。好处是能在原图附近对图片进行局部放大查看,而且可以通过鼠标控制查看的部位。 查看全文 Lazyload 延迟加载效果 Lazyload是通过延迟加载来实现按需加载,达到节省资源,加快浏览速度的目的。网上也有不少类似的效果。 查看全文 图片上传预览效果 图片上传预览是一种在图片上传之前对图片进行本地预览的技术。使用户选择图片后能立即查看图片,而不需上传服务器,提高用户体验。 查看全文 Tween算法及缓动效果 Flash做动画时会用到Tween类,利用它可以做很多动画效果,例如缓动、弹簧等等。我这里要教大家的是怎么利用flash的Tween类的算法,来做js的Tween算法。 查看全文 Table行定位效果 近来有客户要求用table显示一大串数据,由于滚动后就看不到表头,很不方便,所以想到这个效果。 查看全文

程序说明

【基本原理】

通过设置滑动元素的位置坐标(left/right/top/bottom),实现鼠标进入的目标元素滑动展示,其他元素滑动收缩的效果。难点是如何控制多个滑动元素同时进行不同的滑动,这里关键就在于把整体滑动分解成各个滑动元素进行各自的滑动。方法是给各个滑动元素设置目标值,然后各自向自己的目标值滑动,当全部都到达目标值就完成了。

【容器设置】

在_initContainer方法中进行容器设置,由于后面滑动参数的计算要用到容器,所以要先设置容器。先设置容器样式,要实现滑动需要设置容器相对或绝对定位,并且设置overflow为"hidden"来固定容器大小,而滑动元素也要设置绝对定位。

鼠标移出容器时会触发_LEAVE移出函数:

$$E.addEvent( container,  " mouseleave " this ._LEAVE );

其中_LEAVE函数是这样的:

代码 var CLOSE  =  $$F.bind(  this .close,  this  ); this ._LEAVE  =  $$F.bind( function(){    clearTimeout( this ._timerDelay);    $$CE.fireEvent(  this " leave "  );     if  (  this .autoClose ) {  this ._timerDelay  =  setTimeout( CLOSE,  this .delay ); }},  this  );

当autoClose属性为true时才会延时触发close方法。

【滑动对象】

程序初始化时会根据滑动元素创建滑动对象集合。先获取滑动元素:

var nodes  =  opt.nodes  ?  $$A.map( opt.nodes, function(n) {  return  n; } )    : $$A.filter( container.childNodes, function(n) {  return  n.nodeType  ==   1 ; });

如果没有自定义nodes滑动元素,就从容器获取childNodes作为滑动元素。还要用nodeType筛选一下,因为ie外的浏览器都会把空格作为childNodes的一部分。

接着用获取的滑动元素生成程序需要的_nodes滑动对象集合:

this ._nodes  =  $$A.map( nodes, function(node){  return  {  " node " : node }; });

滑动对象用"node"属性记录滑动元素。

然后在_initNodes方法中初始化滑动对象。每个滑动对象都有3个用来计算滑动目标值的属性:defaultTarget默认目标值,max展示尺寸,min收缩尺寸。如果有自定义max尺寸或min尺寸,会根据自定义的尺寸来计算。程序会优先按max来计算:

max  =  Math.max( max  <=   1   ?  max  *  clientSize : Math.min( max, clientSize ), defaultSize );min  =  ( clientSize  -  max )  /  maxIndex;

其中clientSize是容器的可见区域尺寸,defaultSize是平均分配尺寸。如果max是小数或1就按百分比计算,再把尺寸限制在defaultSize到clientSize的范围内。再计算减去max后其他收缩元素的平均尺寸,就可以得到min了。

如果没有自定义max再按自定义min来计算:

min  =  Math.min( min  <   1   ?  min  *  clientSize : min, defaultSize );max  =  clientSize  -  maxIndex  *  min;

同样,如果min是小数就按百分比计算,再做范围限制,然后计算得出max。

最后得到自定义尺寸计算函数:

getMax  =  function(){  return  max; };getMin  =  function(){  return  min; };

如果没有自定义max或min,就根据元素尺寸来计算:

getMax  =  function(o){  return  Math.max( Math.min( o.node[ offset ], clientSize ), defaultSize ); };getMin  =  function(o){  return  ( clientSize  -  o.max )  /  maxIndex; };

把元素尺寸作为展示尺寸来计算,同样要做范围限制,然后计算收缩尺寸。

得到尺寸计算函数后,再用_each方法历遍并设置滑动对象:

o.current  =  o.defaultTarget  =  getDefaultTarget(i);o.max  =  getMax(o); o.min  =  getMin(o);

其中current是当前坐标值,在移动计算时作为开始值的。而defaultTarget是默认目标值,即默认状态时移动的目标值,根据defaultSize和索引得到。

还要设置当鼠标进入滑动元素时触发show展示函数:

代码 var  node  =  o.node, SHOW  =  $$F.bind(  this .show,  this , i );o.SHOW  =  $$F.bind(  function (){    clearTimeout( this ._timerDelay);     this ._timerDelay  =  setTimeout( SHOW,  this .delay );    $$CE.fireEvent(  this " enter " , i );},  this  );$$E.addEvent( node,  " mouseenter " , o.SHOW );

要在滑动元素的"mouseenter"事件中触发,并传递当前滑动对象的索引,再加上延时设置就可以了。

【滑动展示】

当鼠标进入其中一个滑动元素,就会触发show方法开始展示。

首先执行_setMove方法设置滑动参数,并以索引作为参数。在_setMove里面主要是设置计算移动值时需要的目标值、开始值和变化值。先修正索引,错误的索引值会设置为0:

this ._index  =  index  =  index  <   0   ||  index  >  maxIndex  ?   0  : index  |   0 ;

再根据索引获取要展示的滑动对象,通过展示对象的min和max得到getTarget目标值函数:

var nodeShow  =  nodes[ index ], min  =  nodeShow.min, max  =  nodeShow.max;getTarget  =  function(o, i){  return  i  <=  index  ?  min  *  i : min  *  ( i  -   1  )  +  max; };

如果滑动对象就是展示对象或者在展示对象前面,目标值就是min * i,因为第i+1个滑动对象的目标值就是i个min的大小。否则,目标值就是min * ( i - 1 ) + max,其实就是把展示对象的位置换成max。

然后设置每个滑动对象的参数属性:

this ._each( function(o, i){    o.target  =  getTarget(o, i);    o.begin  =  o.current;    o.change  =  o.target  -  o.begin;});

其中target记录目标值,begin通过current得到开始值,目标值和开始值的差就是change改变值。

设置完成后,就执行_easeMove方法开始滑移,在里面重置_time属性为0,再就执行_move程序就正式开始移动了。首先判断_time是否到达duration持续时间,没有到达的话,就继续移动。程序设置了一个_tweenMove移动函数,用来设置缓动:

this ._setPos(  function (o) {     return   this .tween(  this ._time, o.begin, o.change,  this .duration );});

利用tween算法,结合当前时间,开始值,改变值和持续时间,就能得到当前要移动的坐标值。ps:关于tween缓动可以参考tween算法及缓动效果。

当_time到达duration说明滑动已经完成,再执行一次_targetMove目标值移动函数:

this ._setPos( function(o) {  return  o.target; } );

直接移动到目标值,可以防止可能出现的计算误差导致移位不准确。

【关闭和重置】

close方法可以关闭展示,即滑动到默认状态,默认在移出容器时就会执行。默认状态是指全部滑动元素位于defaultTarget默认目标值的状态。先用_setMove设置移动参数,当_setMove没有索引参数时,就会设置目标值为默认目标值:

getTarget  =  function(o){  return  o.defaultTarget; }

完成参数设置后,再执行_easeMove进行滑动,跟滑动展示类似。

reset方法可以重置展示,重置的意思是不进行滑动而直接移动到目标值。如果没有索引参数,就会直接执行_defaultMove默认值移动函数:

this ._setPos( function(o) {  return  o.defaultTarget; } );

直接把滑动元素移动到默认状态。如果有索引参数,就先用_setMove根据索引设置目标值,再执行_targetMove直接移动到目标值。程序初始化后会执行一次reset,并且以自定义defaultIndex作为参数。利用defaultIndex可以一开始就展示对应索引的滑动对象。

【方向模式】

程序可以自定义mode方向模式,有四种方向模式:bottom、top、right、left(默认)。其中right和left是在水平方向滑动,而bottom和top是在垂直方向滑动。而right和left的区别是定点方向不同,left以左边为定点在右边滑动,right就相反。具体参考实例就应该明白了,bottom和top的区别也类似。

程序是通过对不同的方向就修改对应方向的坐标样式来实现的。例如left模式就用"left"样式来做移动效果,top模式就用"top"样式。初始化程序中设置的_pos属性就是用来记录当前模式要使用的坐标样式的:

this ._pos  =   /^ (bottom | top | right | left)$ / .test( opt.mode.toLowerCase() )  ?  RegExp.$ 1  :  " left " ;

然后在_setPos方法中使用_pos指定的坐标样式来设置坐标值:

var  pos  =   this ._pos; this ._each(  function (o, i) {    o.node.style[ pos ]  =  (o.current  =  Math.round(method.call(  this , o )))  +   " px " ;});

 

而_horizontal属性就记录了是否水平方向滑动,即是否right或left。在计算尺寸时,通过它来指定使用用水平还是垂直方向的尺寸。

还有一个_reverse属性,判断是否bottom或right模式。这个属性是为了解决一个问题,例如right模式要实现类似下面的效果:

2 1 0 有两种方法,可以调整元素插入顺序: < div class = " container " >      < div style = " right:0; " > 2 < / div>      < div style = " right:100px; " > 1 < / div>      < div style = " right:200px; " > 0 < / div> < / div>

但这样需要修改dom结构,或者通过zIndex设置堆叠顺序:

< div class = " container " >      < div style = " right:200px;z-index:3; " > 0 < / div>      < div style = " right:100px;z-index:2; " > 1 < / div>      < div style = " right:0;z-index:1; " > 2 < / div> < / div>

显然设置zIndex的方法比较好,程序也用了这个方法。程序就是用_reverse属性来判断是否需要做这些修正。

首先在_initContainer中,根据_reverse重新设置zIndex:

var  zIndex  =   100 , gradient  =   this ._reverse  ?   - 1  :  1 ; this ._each(  function (o){     var  style  =  o.node.style;    style.position  =   " absolute " ; style.zIndex  =  zIndex  +=  gradient;});

在_initNodes中,获取默认目标值时也要判断:

getDefaultTarget  =   this ._reverse     ?  function(i){  return  defaultSize  *  ( maxIndex  -  i ); }    : function(i){  return  defaultSize  *  i; },

当_reverse为true时,由于定点位置是在索引的反方向,设置元素时也应该倒过来设的,所以要用maxIndex减一下。

在_setMove中,根据索引设置滑动目标值时,也要判断:

if  (  this ._reverse ) {    var  get   =  getTarget;    index  =  maxIndex  -  index;    getTarget  =  function(o, i){  return   get ( o, maxIndex  -  i ); }}

不但滑动对象集合的索引要修正,展示对象的索引也要修正。

【自动展示扩展】

这次扩展用的是组合模式,原理参考的ImageZoom扩展篇的扩展模式部分。不同的是加了一个属性扩展,用来添加扩展方法:

$$.extend(  this , prototype );

注意不能添加到SlideView.prototype,这样会影响到SlideView的结构。

“自动展示”要实现的是滑动对象自动轮流展示,并且取消默认状态而实行强制展示,可以用在图片的轮换展示。只要在SlideView后面加入自动展示扩展程序,并且auto参数设为true就会启用。原理也很简单,就是每次滑动/移动完成后,用定时器执行下一次滑动就行了。

首先在"init"初始化程序中,增加一个_NEXT程序,用来展示下一个滑动对象:

this ._NEXT  =  $$F.bind( function(){  this .show(  this ._index  +   1  ); },  this  );

其实就是把当前索引_index加1之后作为show的参数执行。再增加一个_autoNext方法:

if  (  ! this ._autoPause ) {    clearTimeout( this ._autoTimer);     this ._autoTimer  =  setTimeout(  this ._NEXT,  this .autoDelay );}

作用是延时执行_NEXT程序,并且有一个_autoPause属性用来锁定执行。

然后设置几个需要执行的地方。首先在"finish"完成滑动事件中,执行_autoNext方法,这样就实现了基本的自动展示了。在鼠标进入滑动元素后,应该停止自动切换,所以在"enter"进入滑动元素事件中,会清除定时器并把_autoPause设为true来锁定。对应地在"leave"鼠标离开容器事件中,要把_autoPause设回false解除锁定,再执行_autoNext方法重新启动自动程序。并且在"leave"中设置autoClose为false,防止自动恢复默认状态。

最后还要重写reset:

reset.call(  this , index  ==  undefined  ?   this ._index : index ); this ._autoNext();

重写后的reset会强制设置索引来展示,并执行_autoNext进行下一次滑动。

【提示信息扩展】

“提示信息”效果是指每个滑动对象对应有一个提示信息(内容)的层(元素)。这个提示信息会在滑动对象展示时展示,收缩和关闭时关闭。只要加入提示信息扩展程序,并且tip参数设为true就会启用。

提示扩展支持四种位置提示:bottom、top、right、left。在"init"中,根据自定义tipMode获取_tipPos坐标样式:

this ._tipPos  =   /^ (bottom | top | right | left)$ / .test(  this .options.tipPos.toLowerCase() )  ?  RegExp.$ 1  :  " bottom " ;

接着在"initNodes"定义一个能根据滑动元素获取提示元素的函数:

代码 var opt  =   this .options, tipTag  =  opt.tipTag, tipClass  =  opt.tipClass,    re  =  tipClass  &&   new  RegExp( " (^|\\s) "   +  tipClass  +   " (\\s|$) " ),    getTipNode  =   function(node){        var nodes  =  node.getElementsByTagName( tipTag );         if  ( tipClass ) {            nodes  =  $$A.filter( nodes, function(n){  return  re.test(n.className); } );        }         return  nodes[ 0 ];    };

如果自定义了tipTag,就会根据标签来获取元素,否则就按默认值"*"获取全部元素。如果自定义了tipClass,就会再根据className来筛选元素,注意可能包含多个样式,不能直接等于。

得到函数后,再创建提示对象:

代码 this ._each( function(o) {    var node  =  o.node, tipNode  =  getTipNode(node);    node.style.overflow  =   " hidden " ;    tipNode.style.position  =   " absolute " ; tipNode.style.left  =   0 ;        o.tip  =  {         " node " : tipNode,         " show " : tipShow  !=  undefined  ?  tipShow :  0 ,         " close " : tipClose  !=  undefined  ?  tipClose :  - tipNode[offset]    };});

先获取提示元素,并设置相关样式,再给滑动对象添加一个tip属性,保存对应的提示对象。其中"node"属性保存提示元素,"show"是展示时的坐标值,"close"是关闭时的坐标值。如果没有自定义tipShow,默认展示时坐标值是0,即提示元素刚好贴在滑动元素边上的位置;如果没有自定义tipClose,默认关闭时坐标是提示元素的尺寸,即提示元素刚好隐藏在滑动元素外面的位置。

在"setMove"中设置提示移动目标值:

代码 var maxIndex  =   this ._nodes.length  -   1 ; this ._each( function(o, i) {    var tip  =  o.tip;     if  (  this ._reverse ) { i  =  maxIndex  - i; }    tip.target  =  index  ==  undefined  ||  index  !=  i  ?  tip.close : tip.show;    tip.begin  =  tip.current; tip.change  =  tip.target  -  tip.begin;});

这个比滑动对象的设置简单得多,当设置了index参数,并且index等于该滑动对象的索引时才需要展示,其他情况都是隐藏。要注意,跟滑动对象一样,在_reverse为true的时候需要修正索引。在"tweenMove"、"targetMove"、"defaultMove"也要设置对应的移动函数。

为了方便样式设置,扩展了一个_setTipPos方法:

var pos  =   this ._tipPos; this ._each( function(o, i) {    var tip  =  o.tip;    tip.node.style[ pos ]  =  (tip.current  =  method.call(  this , tip ))  +   " px " ;});

根据_tipPos坐标样式来设置坐标值。

使用技巧

【展示尺寸】

要自定义展示尺寸可以通过max和min来设置,可以按像素或百分比来计算。如果不设置的话,就会按照元素本身的尺寸来展示。所以滑动元素展示的尺寸并不需要一致的,程序可以自动计算。

【Accordion效果】

Accordion是可折叠的面板控件,效果类似手风琴,SlideView通过设置也能做到类似的效果。首先把autoClose设为false取消自动关闭,再设置defaultIndex,使SlideView处于展开状态不会关闭。一般Accordion都有一个固定尺寸的标题,这个可以用min来设置。这样就实现了简单的Accordion效果,具体参考第三个实例。

使用说明

实例化时,必须有容器对象或id作为参数:

new  SlideView(  " idSlideView "  );

可选参数用来设置系统的默认属性,包括:属性:    默认值//说明nodes:   null,//自定义展示元素集合mode:   "left",//方向max:   0,//展示尺寸(像素或百分比)min:   0,//收缩尺寸(像素或百分比)delay:   100,//触发延时interval:  20,//滑动间隔duration:  20,//滑动持续时间defaultIndex: null,//默认展示索引autoClose:  true,//是否自动恢复tween:   function(t,b,c,d){ return -c * ((t=t/d-1)*t*t*t - 1) + b; },//tween算子onShow:   function(index){},//滑动展示时执行onClose:  function(){}//滑动关闭执行其中interval、delay、duration、tween、autoClose、onShow、onClose属性可以在程序初始化后动态设置。

还提供了以下方法:show:根据索引滑动展示;close:滑动到默认状态;reset:重置为默认状态或展开索引对应滑动对象;dispose:销毁程序。

要使用自动展示,只要在SlideView后面加入自动展示扩展程序,并且auto参数设为true即可。新增如下可选参数:autoDelay: 2000//展示时间

要使用提示信息,只要加入提示信息扩展程序,并且tip参数设为true即可。新增如下可选参数:属性:    默认值//说明tipPos:  "bottom",//提示位置tipTag:  "*",//提示元素标签tipClass: "",//提示元素样式tipShow: null,//展示时目标坐标tipClose: null//关闭时目标坐标

程序源码   

代码 var  SlideView  =   function (container, options){     this ._initialize( container, options );     this ._initContainer();     this ._initNodes();     this .reset(  this .options.defaultIndex );};SlideView.prototype  =  {   // 初始化程序   _initialize:  function (container, options) {         var  container  =   this ._container  =  $$(container); // 容器对象      this ._timerDelay  =   null ; // 延迟计时器      this ._timerMove  =   null ; // 移动计时器      this ._time  =   0 ; // 时间      this ._index  =   0 ; // 索引          var  opt  =   this ._setOptions(options);         this .interval  =  opt.interval  |   0 ;     this .delay  =  opt.delay  |   0 ;     this .duration  =  opt.duration  |   0 ;     this .tween  =  opt.tween;     this .autoClose  =   !! opt.autoClose;     this .onShow  =  opt.onShow;     this .onClose  =  opt.onClose;         // 设置参数      var  pos  = this ._pos  =   / ^(bottom|top|right|left)$ / .test( opt.mode.toLowerCase() )  ?  RegExp.$ 1  :  " left " ;     this ._horizontal  =   / right|left / .test(  this ._pos );     this ._reverse  =   / bottom|right / .test(  this ._pos );         // 获取滑动元素      var  nodes  =  opt.nodes  ?  $$A.map( opt.nodes,  function (n) {  return  n; } )        : $$A.filter( container.childNodes,  function (n) {  return  n.nodeType  ==   1 ; });     // 创建滑动对象集合      this ._nodes  =  $$A.map( nodes,  function (node){         var  style  =  node.style;         return  {  " node " : node,  " style " : style[pos],  " position " : style.position,  " zIndex " : style.zIndex };    });         // 设置程序      this ._MOVE  =  $$F.bind(  this ._move,  this  );         var  CLOSE  =  $$F.bind(  this .close,  this  );     this ._LEAVE  =  $$F.bind(  function (){        clearTimeout( this ._timerDelay);        $$CE.fireEvent(  this " leave "  );         if  (  this .autoClose ) {  this ._timerDelay  =  setTimeout( CLOSE,  this .delay ); }    },  this  );        $$CE.fireEvent(  this " init "  );  },   // 设置默认属性   _setOptions:  function (options) {     this .options  =  { // 默认值         nodes:             null , // 自定义展示元素集合         mode:             " left " , // 方向         max:             0 , // 展示尺寸(像素或百分比)         min:             0 , // 收缩尺寸(像素或百分比)         delay:             100 , // 触发延时         interval:         20 , // 滑动间隔         duration:         20 , // 滑动持续时间         defaultIndex:     null , // 默认展示索引         autoClose:         true , // 是否自动恢复         tween:             function (t,b,c,d){  return   - *  ((t = t / d-1)*t*t*t - 1) + b; }, // tween算子         onShow:             function (index){}, // 滑动展示时执行         onClose:         function (){} // 滑动关闭执行     };     return  $$.extend( this .options, options  ||  {});  },   // 设置容器   _initContainer:  function () {     // 容器样式设置      var  container  =   this ._container, style  =  container.style, position  =  $$D.getStyle( container,  " position "  );     this ._style  =  {  " position " : style.position,  " overflow " : style.overflow }; // 备份样式      if  ( position  !=   " relative "   &&  position  !=   " absolute "  ) { style.position  =   " relative " ; }    style.overflow  =   " hidden " ;     // 移出容器时     $$E.addEvent( container,  " mouseleave " this ._LEAVE );     // 设置滑动元素      var  zIndex  =   100 , gradient  =   this ._reverse  ?   - 1  :  1 ;     this ._each(  function (o){         var  style  =  o.node.style;        style.position  =   " absolute " ; style.zIndex  =  zIndex  +=  gradient;    });        $$CE.fireEvent(  this " initContainer "  );  },   // 设置滑动对象   _initNodes:  function () {     var  len  =   this ._nodes.length, maxIndex  =  len  -   1 ,        type  =   this ._horizontal  ?   " Width "  :  " Height " , offset  =   " offset "   +  type,        clientSize  =   this ._container[  " client "   +  type ],        defaultSize  =  Math.round( clientSize  /  len ),         // 计算默认目标值的函数         getDefaultTarget  =   this ._reverse             ?   function (i){  return  defaultSize  *  ( maxIndex  -  i ); }            :  function (i){  return  defaultSize  *  i; },        max  =   this .options.max, min  =   this .options.min, getMax, getMin;     // 设置参数函数      if  ( max  >   0   ||  min  >   0  ) { // 自定义参数值          // 小数按百分比设置          if  ( max  >   0   ) {            max  =  Math.max( max  <=   1   ?  max  *  clientSize : Math.min( max, clientSize ), defaultSize );            min  =  ( clientSize  -  max )  /  maxIndex;        }  else  {            min  =  Math.min( min  <   1   ?  min  *  clientSize : min, defaultSize );            max  =  clientSize  -  maxIndex  *  min;        }        getMax  =   function (){  return  max; };        getMin  =   function (){  return  min; };    }  else  { // 根据元素尺寸设置参数值         getMax  =   function (o){  return  Math.max( Math.min( o.node[ offset ], clientSize ), defaultSize ); };        getMin  =   function (o){  return  ( clientSize  -  o.max )  /  maxIndex; };    }         // 设置滑动对象      this ._each(  function (o, i){         // 移入滑动元素时执行程序          var  node  =  o.node, SHOW  =  $$F.bind(  this .show,  this , i );        o.SHOW  =  $$F.bind(  function (){            clearTimeout( this ._timerDelay);             this ._timerDelay  =  setTimeout( SHOW,  this .delay );            $$CE.fireEvent(  this " enter " , i );        },  this  );        $$E.addEvent( node,  " mouseenter " , o.SHOW );         // 计算尺寸         o.current  =  o.defaultTarget  =  getDefaultTarget(i); // 默认目标值         o.max  =  getMax(o); o.min  =  getMin(o);    });        $$CE.fireEvent(  this " initNodes "  );  },     // 根据索引滑动展示   show:  function (index) {     this ._setMove( index  |   0  );     this .onShow(  this ._index );     this ._easeMove();  },   // 滑动到默认状态   close:  function () {     this ._setMove();     this .onClose();     this ._easeMove();  },   // 重置为默认状态或展开索引对应滑动对象   reset:  function (index) {    clearTimeout( this ._timerDelay);     if  ( index  ==  undefined ) {         this ._defaultMove();    }  else  {         this ._setMove(index);         this .onShow(  this ._index );         this ._targetMove();    }  },     // 设置滑动参数   _setMove:  function (index) {     var  setTarget; // 设置目标值函数      if  ( index  ==  undefined ) { // 设置默认状态目标值         getTarget  =   function (o){  return  o.defaultTarget; }    }  else  { // 根据索引设置滑动目标值          var  nodes  =   this ._nodes, maxIndex  =  nodes.length  -   1 ;         // 设置索引          this ._index  =  index  =  index  <   0   ||  index  >  maxIndex  ?   0  : index  |   0 ;         // 设置展示参数          var  nodeShow  =  nodes[ index ], min  =  nodeShow.min, max  =  nodeShow.max;        getTarget  =   function (o, i){  return  i  <=  index  ?  min  *  i : min  *  ( i  -   1  )  +  max; };         if  (  this ._reverse ) {             var  get  =  getTarget;            index  =  maxIndex  -  index;            getTarget  =   function (o, i){  return  get( o, maxIndex  -  i ); }        }    }     this ._each(  function (o, i){        o.target  =  getTarget(o, i); // 设置目标值         o.begin  =  o.current; // 设置开始值         o.change  =  o.target  -  o.begin; // 设置变化值     });    $$CE.fireEvent(  this " setMove " , index );  },     // 滑移程序   _easeMove:  function () {     this ._time  =   0 this ._move();  },   // 移动程序   _move:  function () {     if  (  this ._time  <   this .duration ){ // 未到达          this ._tweenMove();         this ._time ++ ;         this ._timerMove  =  setTimeout(  this ._MOVE,  this .interval );    }  else  { // 完成          this ._targetMove(); // 防止计算误差         $$CE.fireEvent(  this " finish "  );    }  },     // tween移动函数   _tweenMove:  function () {     this ._setPos(  function (o) {         return   this .tween(  this ._time, o.begin, o.change,  this .duration );    });    $$CE.fireEvent(  this " tweenMove "  );  },   // 目标值移动函数   _targetMove:  function () {     this ._setPos(  function (o) {  return  o.target; } );    $$CE.fireEvent(  this " targetMove "  );  },   // 默认值移动函数   _defaultMove:  function () {     this ._setPos(  function (o) {  return  o.defaultTarget; } );    $$CE.fireEvent(  this " defaultMove "  );  },   // 设置坐标值   _setPos:  function (method) {    clearTimeout( this ._timerMove);     var  pos  =   this ._pos;     this ._each(  function (o, i) {        o.node.style[ pos ]  =  (o.current  =  Math.round(method.call(  this , o )))  +   " px " ;    });  },     // 历遍滑动对象集合   _each:  function (callback) {    $$A.forEach(  this ._nodes, callback,  this  );  },     // 销毁程序   dispose:  function () {    clearTimeout( this ._timerDelay);    clearTimeout( this ._timerMove);        $$CE.fireEvent(  this " dispose "  );         var  pos  =   this ._pos;     this ._each(  function (o) {         var  style  =  o.node.style;        style[pos]  =  o.style; style.zIndex  =  o.zIndex; style.position  =  o.position; // 恢复样式         $$E.removeEvent( o.node,  " mouseenter " , o.SHOW ); o.SHOW  =  o.node  =   null ;    });    $$E.removeEvent(  this ._container,  " mouseleave " this ._LEAVE );        $$D.setStyle(  this ._container,  this ._style );         this ._container  =   this ._nodes  =   this ._MOVE  =   this ._LEAVE  =   null ;    $$CE.clearEvent(  this  );  }};

 

自动展示扩展 

代码 SlideView.prototype._initialize  =  ( function (){     var  init  =  SlideView.prototype._initialize,        reset  =  SlideView.prototype.reset,        methods  =  {             " init " function (){                 this .autoDelay  =   this .options.autoDelay  |   0 ;                                 this ._autoTimer  =   null ; // 定时器                  this ._autoPause  =   false ; // 暂停自动展示                  // 展示下一个滑动对象                  this ._NEXT  =  $$F.bind(  function (){  this .show(  this ._index  +   1  ); },  this  );            },             " leave " function (){                 this .autoClose  =   this ._autoPause  =   false ;                 this ._autoNext();            },             " enter " function (){                clearTimeout( this ._autoTimer);                 this ._autoPause  =   true ;            },             " finish " function (){                 this ._autoNext();            },             " dispose " function (){                clearTimeout( this ._autoTimer);            }        },        prototype  =  {            _autoNext:  function (){                 if  (  ! this ._autoPause ) {                    clearTimeout( this ._autoTimer);                     this ._autoTimer  =  setTimeout(  this ._NEXT,  this .autoDelay );                }            },            reset:  function (index) {                reset.call(  this , index  ==  undefined  ?   this ._index : index );                 this ._autoNext();            }        };     return   function (){         var  options  =  arguments[ 1 ];         if  ( options  &&  options.auto ) {             // 扩展options             $$.extend( options, {                autoDelay:     2000 // 展示时间             },  false  );             // 扩展属性             $$.extend(  this , prototype );             // 扩展钩子             $$A.forEach( methods,  function ( method, name ){                $$CE.addEvent(  this , name, method );            },  this  );        }        init.apply(  this , arguments );    }})();

提示信息扩展 

代码 SlideView.prototype._initialize  =  ( function (){     var  init  =  SlideView.prototype._initialize,        methods  =  {             " init " function (){                 // 坐标样式                  this ._tipPos  =   / ^(bottom|top|right|left)$ / .test(  this .options.tipPos.toLowerCase() )  ?  RegExp.$ 1  :  " bottom " ;            },             " initNodes " function (){                 var  opt  =   this .options, tipTag  =  opt.tipTag, tipClass  =  opt.tipClass,                    re  =  tipClass  &&   new  RegExp( " (^|\\s) "   +  tipClass  +   " (\\s|$) " ),                    getTipNode  =    function (node){                         var  nodes  =  node.getElementsByTagName( tipTag );                         if  ( tipClass ) {                            nodes  =  $$A.filter( nodes,  function (n){  return  re.test(n.className); } );                        }                         return  nodes[ 0 ];                    };                 // 设置提示对象                  var  tipShow  =  opt.tipShow, tipClose  =  opt.tipClose,                    offset  =   / right|left / .test(  this ._tipPos )  ?   " offsetWidth "  :  " offsetHeight " ;                 this ._each(  function (o) {                     var  node  =  o.node, tipNode  =  getTipNode(node);                    node.style.overflow  =   " hidden " ;                    tipNode.style.position  =   " absolute " ; tipNode.style.left  =   0 ;                     // 创建提示对象                     o.tip  =  {                         " node " : tipNode,                         " show " : tipShow  !=  undefined  ?  tipShow :  0 ,                         " close " : tipClose  !=  undefined  ?  tipClose :  - tipNode[offset]                    };                });            },             " setMove " function (index){                 var  maxIndex  =   this ._nodes.length  -   1 ;                 this ._each(  function (o, i) {                     var  tip  =  o.tip;                     if  (  this ._reverse ) { i  =  maxIndex  - i; }                    tip.target  =  index  ==  undefined  ||  index  !=  i  ?  tip.close : tip.show;                    tip.begin  =  tip.current; tip.change  =  tip.target  -  tip.begin;                });            },             " tweenMove " function (){                 this ._setTipPos(  function (tip) {                     return  Math.round(  this .tween(  this ._time, tip.begin, tip.change,  this .duration ) );                });            },             " targetMove " function (){                 this ._setTipPos(  function (tip){  return  tip.target; });            },             " defaultMove " function (){                 this ._setTipPos(  function (tip){  return  tip.close; });            },             " dispose " function (){                 this ._each(  function (o){ o.tip  =   null ; });            }        },        prototype  =  {             // 设置坐标值函数             _setTipPos:  function (method) {                 var  pos  =   this ._tipPos;                 this ._each(  function (o, i) {                     var  tip  =  o.tip;                    tip.node.style[ pos ]  =  (tip.current  =  method.call(  this , tip ))  +   " px " ;                });            }        };     return   function (){         var  options  =  arguments[ 1 ];         if  ( options  &&  options.tip  ==   true  ) {             // 扩展options             $$.extend( options, {                tipPos:         " bottom " , // 提示位置                 tipTag:         " * " , // 提示元素标签                 tipClass:     "" , // 提示元素样式                 tipShow:     null , // 展示时目标坐标                 tipClose:     null // 关闭时目标坐标             },  false  );             // 扩展属性             $$.extend(  this , prototype );             // 扩展钩子             $$A.forEach( methods,  function ( method, name ){                $$CE.addEvent(  this , name, method );            },  this  );        }        init.apply(  this , arguments );    }})();

 

 完整实例下载

转载于:https://www.cnblogs.com/cloudgamer/archive/2010/07/29/SlideView.html

相关资源:数据结构—成绩单生成器
最新回复(0)