[转帖]Mootools源码分析-36 -- Fx.Slide

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

原作者:我佛山人

 

代码
//滑入滑出效果,需要创建一个包装容器,再配合margin来实现

Fx.Slide 
= new Class({
    
//继承自Fx
    Extends: Fx,
    options: {
        mode: 
'vertical'
    },

    
//覆盖父类Fx的同名构造函数
    initialize: function(element, options)    {
        
//添加onComplete事件,以修正open属性标记的值
        this.addEvent('onComplete'function()    {
            
this.open = (this.wrapper['offset' + this.layout.capitalize()] != 0);
            
if (this.open && Browser.Engine.webkit419) this.element.dispose().inject(this.wrapper);
        }, 
true);

        
//特效的作用对象
        this.element = this.subject = $(element);
        
//调用父类Fx的同名方法
        arguments.callee.parent(options);
        
//先从缓存对象中取当前作用对象的包装容器
        var wrapper = this.element.retrieve('wrapper');
        
//如果未缓存则创建
        this.wrapper = wrapper || new Element('div', {
            styles: $extend(
this.element.getStyles('margin''position'), {'overflow''hidden'})
        }).wraps(
this.element);
        
//缓存
        this.element.store('wrapper'this.wrapper).setStyle('margin'0);
        
this.now = [];
        
//滑动状态标记
        this.open = true;
    },
    
//垂直方向滑动时的关键属性设置
    vertical: function()    {
        
//垂直滑动时主要使用margin-top属性,控制作用对象在包装窗口的垂直位置
        this.margin = 'margin-top';
        
//包装容器的高度属性
        this.layout = 'height';
        
//包装窗口的高度值
        this.offset = this.element.offsetHeight;
    },

    
//水平方向滑动时的关键属性设置
    horizontal: function()    {
        
//水平滑动时主要使用margin-left属性,控制作用对象在包装窗口的水平位置
        this.margin = 'margin-left';
        
//包装容器的宽度属性
        this.layout = 'width';
        
//包装窗口的宽度值
        this.offset = this.element.offsetWidth;
    },
    
//设置目标值
    set: function(now)    {
        
//设置作用对象在包装容器内的水平或垂直位置
        this.element.setStyle(this.margin, now[0]);
        
//设置包装窗口的宽度或高度值
        this.wrapper.setStyle(this.layout, now[1]);
        
return this;
    },

    
//根据初始值,结束值和变量求目标值
    compute: function(from, to, delta)    {
        
var now = [];
        
//Ruby风格的两次循环,转为from和to是长度为2的数组
        (2).times(function(i)    {
            now[i] 
= Fx.compute(from[i], to[i], delta);
        });
        
return now;
    },

    
//开始滑动
    start: function(how, mode)    {
        
//检查约束
        if (!this.check(how, mode))    return this;
        
//根据配置参数选择滑动模式的相关属性
        this[mode || this.options.mode]();
        
//取当前作用对象的外补白值
        var margin = this.element.getStyle(this.margin).toInt();
        
//取包装容器的尺寸
        var layout = this.wrapper.getStyle(this.layout).toInt();
        
//测入时的目标值集合
        var caseIn = [[margin, layout], [0this.offset]];
        
//测出时的目标值集合
        var caseOut = [[margin, layout], [-this.offset, 0]];
        
var start;
        
//滑动方式选择
        switch (how)    {
            
case 'in': start = caseIn; break;
            
case 'out': start = caseOut; break;
            
case 'toggle': start = (this.wrapper['offset' + this.layout.capitalize()] == 0? caseIn : caseOut;
        }
        
return arguments.callee.parent(start[0], start[1]);
    },
    
//滑入的快捷方法
    slideIn: function(mode)    {
        
return this.start('in', mode);
    },

    
//滑出的快捷方法
    slideOut: function(mode)    {
        
return this.start('out', mode);
    },

    
//隐藏滑动对象
    hide: function(mode)    {
        
this[mode || this.options.mode]();
        
//显示隐藏的标记
        this.open = false;
        
return this.set([-this.offset, 0]);
    },

    
//显示滑动对象
    show: function(mode)    {
        
this[mode || this.options.mode]();
        
//显示隐藏的标记
        this.open = true;
        
return this.set([0this.offset]);
    },

    
//开关
    滑动的快捷方法
    toggle: 
function(mode)    {
        
return this.start('toggle', mode);
    }
});

//为Element添加slide属性
Element.Properties.slide = {
    
//setter
    set: function(options)    {
        
//从缓存对象读取作用于当前Element的Fx.Slide实例
        var slide = this.retrieve('slide');
        
//如果缓存中存在Fx.Slide实例
        //取消执行
        if (slide)    slide.cancel();
        
//缓存Fx.Slide对象的配置参数
        return this.eliminate('slide').store('slide:options', $extend({link: 'cancel'}, options));
    },

    
//getter
    get: function(options)    {
        
//如果提供配置参数或不存在缓存的Fx.Slider实例
        if (options || !this.retrieve('slide'))    {
            
//缓存配置参数
            if (options || !this.retrieve('slide:options'))    this.set('slide', options);
            
//缓存Fx.Slide实例
            this.store('slide'new Fx.Slide(thisthis.retrieve('slide:options')));
        }
        
//从缓存对象读取Fx.Slider实例返回
        return this.retrieve('slide');
    }
};

//扩展的slide方法
Element.implement({
    
//为Element添加的Fx.Slide快捷方法
    slide: function(how, mode)    {
        
//指定滑动方式
        how = how || 'toggle';
        
//取缓存中的Fx.Slide实例
        var slide = this.get('slide'), toggle;
        
//不同滑动方式的处理
        switch (how)    {
            
case 'hide': slide.hide(mode); break;
            
case 'show': slide.show(mode); break;
            
case 'toggle':
                
//先从缓存对象取状态标记
                var flag = this.retrieve('slide:flag', slide.open);
                
//根据标记执行滑入还是滑出
                slide[(flag) ? 'slideOut' : 'slideIn'](mode);
                
//缓存状态标记
                this.store('slide:flag'!flag);
                
//表明本次执行定了how的参数值为toggle,如果不false,下面将会删除缓存的标记
                toggle = true;
                
break;
            
//默认滑动方式
            default: slide.start(how, mode);
        }
        
//如果没有使用toggle滑动方式,删除缓存的标记
        if (!toggle)    this.eliminate('slide:flag');
        
return this;
    }
});

 

posted @ 2009-11-27 14:31  webgis松鼠  阅读(298)  评论(0)    收藏  举报