[转帖]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], [0, this.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([0, this.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(this, this.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;
}
});
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], [0, this.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([0, this.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(this, this.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;
}
});


浙公网安备 33010602011771号