[转帖]Mootools源码分析-50 -- Accordion

原帖地址:http://space.flash8.net/space/?uid-18713-action-viewspace-itemid-410510

原作者:我佛山人

 

ExpandedBlockStart.gif 代码
// 类似手风琴的伸缩效果,需要结合Fx.Elements理解
//
演示:http://demos.mootools.net/Accordion

var  Accordion  =   new  Class({

    
// 继承自Fx.Elements
    Extends: Fx.Elements,

    options: {
/*
        //伸展显示事件
        onActive: $empty,
        //压缩隐藏事件
        onBackground: $empty,
*/
        
// 显示的索引值
        display:  0 ,
        
// 显示的索引值
        show:  false ,
        
// 高度的显示方式
        height:  true ,
        
// 宽度的显示方式
        width:  false ,
        
// 透明度的显示方式
        opacity:  true ,
        
// 是否固定高度
        fixedHeight:  false ,
        
// 是否固定宽度
        fixedWidth:  false ,
        
// 是否等待前一次动画结束
        wait:  false ,
        
// 永远隐藏
        alwaysHide:  false
    },

    
// 构造函数
    initialize:  function ()    {
        
// 利用Array.link读取参数并归类
         var  params  =  Array.link(arguments, { ' container ' : Element.type,  ' options ' : Object.type,  ' togglers ' : $defined,  ' elements ' : $defined});
        
// 调用父类Fx.Elements的同名方法
        arguments.callee.parent(params.elements, params.options);
        
// 取能toggle的Elements(点击时伸缩的对象)
         this .togglers  =  $$(params.togglers);
        
// 整个UI容器
         this .container  =  $(params.container);
        
// 最后激活的对象索引
         this .previous  =   - 1 ;
        
// 如果设置
         if  ( this .options.alwaysHide)     this .options.wait  =   true ;
        
// 如果设置显示的索引值
         if  ($chk( this .options.show))    {
            
// 忽略display的设置
             this .options.display  =   false ;
            
// 更新指向
             this .previous  =   this .options.show;
        }
        
// 如果手工执行start方法
         if  ( this .options.start)    {
            
// 忽略display指定的值
             this .options.display  =   false ;
            
// 忽略show指定的值
             this .options.show  =   false ;
        }
        
// 提供Fx.Eleemnts中变化的属性集
         this .effects  =  {};
        
// 如果指定透明度,设效果中的透明属性值为完全透明
         if  ( this .options.opacity)     this .effects.opacity  =   ' fullOpacity ' ;
        
// 如果指定宽度,当同时指定固定宽度时,设效果中的宽度属性值为全尺寸宽度,否则为当前宽度
         if  ( this .options.width)     this .effects.width  =   this .options.fixedWidth  ?   ' fullWidth '  :  ' offsetWidth ' ;
        
// 如果指定高度,当同时指定固定高度时,设效果中的高度属性值为全尺寸宽度,否则为当前高度
         if  ( this .options.height)     this .effects.height  =   this .options.fixedHeight  ?   ' fullHeight '  :  ' scrollHeight ' ;
        
// 遍历处理,为每一项添加事件
         for  ( var  i  =   0 , l  =   this .togglers.length; i  <  l; i ++ this .addSection( this .togglers[i],  this .elements[i]);
        
// 遍历找到显示的指定项
         this .elements.each( function (el, i)    {
            
// 如果指定显示当前项
             if  ( this .options.show  ===  i)    {
                
// 触发onActive事件
                 this .fireEvent( ' onActive ' , [ this .togglers[i], el]);
            }    
else     {
                
// 设置非显示项的相关CSS属性为0
                 for  ( var  fx  in   this .effects)    el.setStyle(fx,  0 );
            }
        }, 
this );
        
// 如果display有定义非0值,
         if  ($chk( this .options.display))     this .display( this .options.display);
    },

    
// 添加节点
     // togger为伸缩句柄,eleemnt为内容容器,pos为添加到的位置索引
    addSection:  function (toggler, element, pos)    {
        
// 取对象
        toggler  =  $(toggler);
        element 
=  $(element);
        
// 测试togglers集合中是否已包含toggler
         var  test  =   this .togglers.contains(toggler);
        
// 取集合长度
         var  len  =   this .togglers.length;
        
// 将toggler包含进togglers集合
         this .togglers.include(toggler);
        
// 将element包含进elements集合
         this .elements.include(element);
        
// 如果集合不为空,并且不包含当前项或添加位置大于0
         if  (len  &&  ( ! test  ||  pos))    {
            
// 取合法的位置
            pos  =  $pick(pos, len  -   1 );
            
// 插入到指定索引的项前
            toggler.inject( this .togglers[pos],  ' before ' );
            
// 内容容器插入其后
            element.inject(toggler,  ' after ' );
            
// 否则,如果指定父容器并且不在集合中
        }     else   if     ( this .container  &&   ! test)    {
            
// 插入到父容器中
            toggler.inject( this .container);
            element.inject(
this .container);
        }
        
// 取当前索引值
         var  idx  =   this .togglers.indexOf(toggler);
        
// 添加单击事件监听,在单击时显示当前索引位置上的对象
        toggler.addEvent( ' click ' this .display.bind( this , idx));
        
// 如果指定高度,为了兼容,将会影响高度值的padding和boder的上下值置0
         if  ( this .options.height)    element.setStyles({ ' padding-top ' 0 ' border-top ' ' none ' ' padding-bottom ' 0 ' border-bottom ' ' none ' });
        
// 如果指定宽度,为了兼容,将会影响宽度值的padding和boder的左右值置0
         if  ( this .options.width)    element.setStyles({ ' padding-left ' 0 ' border-left ' ' none ' ' padding-right ' 0 ' border-right ' ' none ' });
        element.fullOpacity 
=   1 ;
        
// 如果设置固定宽度
         if  ( this .options.fixedWidth) element.fullWidth  =   this .options.fixedWidth;
        
// 如果设置固定高度
         if  ( this .options.fixedHeight) element.fullHeight  =   this .options.fixedHeight;
        
// 剪切溢出内容
        element.setStyle( ' overflow ' ' hidden ' );
        
// 如果集合中不包含当前项
         if  ( ! test)    {
            
// 设置容器相关CSS属性为0
             for  ( var  fx  in   this .effects)    element.setStyle(fx,  0 );
        }
        
return   this ;
    },

    
// 显示指定索引位置上的项
    display:  function (index)    {
        
// 如果参数类型为对象,取对象在集合中的索引
        index  =  ($type(index)  ==   ' element ' ?   this .elements.indexOf(index) : index;
        
// 如果已经开始显示并且设置要等待,或者指定索引与最后显示的相同并且不是指定永远隐藏,退出处理
         if  (( this .timer  &&   this .options.wait)  ||  (index  ===   this .previous  &&   ! this .options.alwaysHide))  return   this ;
        
// 更新最后索引的指向
         this .previous  =  index;
        
var  ōbj  =  {};
        
// 遍历其余项,取得变化的属性集合,为start方法提供参数
         this .elements.each( function (el, i)    {
            obj[i] 
=  {};
            
// 计算需要隐藏的项
             var  hide  =  (i  !=  index)  ||  ( this .options.alwaysHide  &&  (el.offsetHeight  >   0 ));
            
// 根据显示或隐藏触发不同的事件
             this .fireEvent(hide  ?   ' onBackground '  :  ' onActive ' , [ this .togglers[i], el]);
            
// 隐藏时设置每个属性值为0
             for  ( var  fx  in   this .effects)    obj[i][fx]  =  hide  ?   0  : el[ this .effects[fx]];
        }, 
this );
        
// 开始执行效果
         return   this .start(obj);
    }
});

 

 

转载于:https://www.cnblogs.com/maapaa/articles/mootools-s-50.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值