[转帖]Mootools源码分析-47 -- Scroller
原帖地址:http://space.flash8.net/space/?uid-18713-action-viewspace-itemid-409748
原作者:我佛山人
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
//滚动的效果
//演示:http://demos.mootools.net/Scroller
var Scroller = new Class({
//继承自Events和Options,UI插件的特征
Implements: [Events, Options],
options: {
//使对象滚动的范围值
area: 20,
//滚动速度
velocity: 1,
//滚动位置改变时的事件
onChange: function(x, y) {
this.element.scrollTo(x, y);
}
},
//构造函数
initialize: function(element, options) {
//合并参数
this.setOptions(options);
//作用的当前对象
this.element = $(element);
//监听鼠标事件的对象
this.listener = ($type(this.element) != 'element') ? $(this.element.getDocument().body) : this.element;
this.timer = null;
},
//开始滚动
start: function() {
//为getCoords方法闭包绑定当前对象
this.coord = this.getCoords.bind(this);
//添加鼠标移动事件监听
this.listener.addEvent('mousemove', this.coord);
},
//停止滚动
stop: function() {
//移除鼠标事件监听
this.listener.removeEvent('mousemove', this.coord);
//清除计时器
this.timer = $clear(this.timer);
},
//取得鼠标坐标
getCoords: function(event) {
//取鼠标坐标信息
this.page = (this.listener.get('tag') == 'body') ? event.client : event.page;
//如果未启动计时器,启动之,每50秒执行scroll方法
if (!this.timer) this.timer = this.scroll.periodical(50, this);
},
//滚动处理
scroll: function() {
//获取当前对象的尺寸,滚动条及坐标信息
var size = this.element.getSize(), scroll = this.element.getScroll(), pos = this.element.getPosition(), change = {'x': 0, 'y': 0};
//分别处理坐标系上的方向
for (var z in this.page) {
//如果鼠标在对象区域内,并且当前方向上的滚动位置不为0
if (this.page[z] < (this.options.area + pos[z]) && scroll[z] != 0)
//往回滚(由上面的比较可知结果为负值)
change[z] = (this.page[z] - this.options.area - pos[z]) * this.options.velocity;
//如果鼠标在右/下方向移动,并且当前对象不是刚好两屏
else if (this.page[z] + this.options.area > (size[z] + pos[z]) && size[z] + size[z] != scroll[z])
//向前滚(由上面的比较可知结果为正值)
change[z] = (this.page[z] - size[z] + this.options.area - pos[z]) * this.options.velocity;
}
//只要有一个方向上的滚动值有需要改变,触发onChange事件,传递最终需要滚动到的坐标值
if (change.y || change.x) this.fireEvent('onChange', [scroll.x + change.x, scroll.y + change.y]);
}
});
//演示:http://demos.mootools.net/Scroller
var Scroller = new Class({
//继承自Events和Options,UI插件的特征
Implements: [Events, Options],
options: {
//使对象滚动的范围值
area: 20,
//滚动速度
velocity: 1,
//滚动位置改变时的事件
onChange: function(x, y) {
this.element.scrollTo(x, y);
}
},
//构造函数
initialize: function(element, options) {
//合并参数
this.setOptions(options);
//作用的当前对象
this.element = $(element);
//监听鼠标事件的对象
this.listener = ($type(this.element) != 'element') ? $(this.element.getDocument().body) : this.element;
this.timer = null;
},
//开始滚动
start: function() {
//为getCoords方法闭包绑定当前对象
this.coord = this.getCoords.bind(this);
//添加鼠标移动事件监听
this.listener.addEvent('mousemove', this.coord);
},
//停止滚动
stop: function() {
//移除鼠标事件监听
this.listener.removeEvent('mousemove', this.coord);
//清除计时器
this.timer = $clear(this.timer);
},
//取得鼠标坐标
getCoords: function(event) {
//取鼠标坐标信息
this.page = (this.listener.get('tag') == 'body') ? event.client : event.page;
//如果未启动计时器,启动之,每50秒执行scroll方法
if (!this.timer) this.timer = this.scroll.periodical(50, this);
},
//滚动处理
scroll: function() {
//获取当前对象的尺寸,滚动条及坐标信息
var size = this.element.getSize(), scroll = this.element.getScroll(), pos = this.element.getPosition(), change = {'x': 0, 'y': 0};
//分别处理坐标系上的方向
for (var z in this.page) {
//如果鼠标在对象区域内,并且当前方向上的滚动位置不为0
if (this.page[z] < (this.options.area + pos[z]) && scroll[z] != 0)
//往回滚(由上面的比较可知结果为负值)
change[z] = (this.page[z] - this.options.area - pos[z]) * this.options.velocity;
//如果鼠标在右/下方向移动,并且当前对象不是刚好两屏
else if (this.page[z] + this.options.area > (size[z] + pos[z]) && size[z] + size[z] != scroll[z])
//向前滚(由上面的比较可知结果为正值)
change[z] = (this.page[z] - size[z] + this.options.area - pos[z]) * this.options.velocity;
}
//只要有一个方向上的滚动值有需要改变,触发onChange事件,传递最终需要滚动到的坐标值
if (change.y || change.x) this.fireEvent('onChange', [scroll.x + change.x, scroll.y + change.y]);
}
});