I'm using the following class along with Mootools to create custom scrolling areas on a site. It includes a mousewheel event. I need to be able to fire an onComplete once the scroller comes to a stop after using the mousewheel. So say you swipe the mousewheel to scroll, I need to fire an oncomplete once the scrolling content comes to a stop.
Suggestions?
var ScrollBar = new Class({
Implements: [Events, Options],
options: {
wheel: (Browser.safari5) ? 1 : 20
},
initialize: function(main, options) {
this.setOptions(options);
this.dragging = f开发者_开发问答alse;
this.inside = false;
this.main = $(main);
this.content = this.main.getFirst();
this.vScrollbar = new Element('div', {
'class': 'scrollbar'
}).inject(this.content, 'after');
this.vTrack = new Element('div', {
'class': 'track'
}).inject(this.vScrollbar);
this.vThumb = new Element('div', {
'class': 'handle'
}).inject(this.vTrack);
this.bound = {
'vStart': this.vStart.bind(this),
'end': this.end.bind(this),
'vDrag': this.vDrag.bind(this),
'wheel': this.wheel.bind(this),
'vPage': this.vPage.bind(this)
};
// set scrollarea mousein/out hide of scrollbar
this.vScrollbar.set('tween', {
duration: 200,
transition: 'cubic:out'
});
this.main.addEvent('mouseenter', function(event){
this.inside = true;
this.vScrollbar.get('tween').cancel();
this.vScrollbar.tween('width', 12);
}.bind(this));
this.main.addEvent('mouseleave', function(event){
this.inside = false;
if (!this.dragging) {
this.vScrollbar.get('tween').cancel();
this.vScrollbar.tween('width', 0);
}
}.bind(this));
this.vPosition = {};
this.vMouse = {};
this.update();
this.attach();
this.scrollContent = new Fx.Scroll(this.content, {
duration: 500,
transition: Fx.Transitions.Cubic.easeOut,
onComplete: function(){
Blinds.updateImages();
}
});
this.scrollThumb = new Fx.Morph(this.vThumb, {
duration: 500,
transition: Fx.Transitions.Cubic.easeOut
});
},
update: function() {
var panel_id = (this.content.getFirst()) ? this.content.getFirst().get('id') : '';
if ((this.content.scrollHeight <= this.main.offsetHeight) || panel_id === 'random-doodle' || (this.content.getFirst() && this.content.getFirst().hasClass('collapsed'))) {
this.main.addClass('noscroll');
return false;
}
else { this.main.removeClass('noscroll'); }
this.vContentSize = this.content.offsetHeight;
this.vContentScrollSize = this.content.scrollHeight;
this.vTrackSize = this.vTrack.offsetHeight;
this.vContentRatio = this.vContentSize / this.vContentScrollSize;
this.vThumbSize = 200;
this.vThumb.setStyle('height', this.vThumbSize);
this.vScrollRatio = this.vContentScrollSize / (this.vTrackSize - this.vThumbSize) - this.vContentRatio * (this.vContentScrollSize / (this.vTrackSize - this.vThumbSize));
this.vUpdateThumbFromContentScroll();
this.vUpdateContentFromThumbPosition();
},
vUpdateContentFromThumbPosition: function() {
this.content.scrollTop = this.vPosition.now * this.vScrollRatio;
},
vUpdateContentFromThumbPosition2: function() {
var pos = this.vPosition.now * this.vScrollRatio;
this.scrollContent.start(0, pos);
},
vUpdateThumbFromContentScroll: function() {
this.vPosition.now = (this.content.scrollTop / this.vScrollRatio).limit(0, (this.vTrackSize - this.vThumbSize));
this.vThumb.setStyle('top', this.vPosition.now);
},
vUpdateThumbFromContentScroll2: function(pos) {
this.vPosition.now = (this.content.scrollTopNew / this.vScrollRatio).limit(0, (this.vTrackSize - this.vThumbSize));
this.scrollThumb.start({
'top': this.vPosition.now
});
},
attach: function() {
if (this.options.wheel) { this.content.addEvent('mousewheel', this.bound.wheel); }
this.vThumb.addEvent('mousedown', this.bound.vStart);
this.vTrack.addEvent('mouseup', this.bound.vPage);
},
wheel: function(event) {
this.content.scrollTop -= event.wheel * this.options.wheel;
this.vUpdateThumbFromContentScroll();
event.stop();
},
scrollTo: function(pos){
myInstance = this;
this.content.scrollTopNew = pos;
this.scrollContent.start(0, this.content.scrollTopNew);
myInstance.vUpdateThumbFromContentScroll2(pos);
},
vPage: function(event) {
// if scrolling up
if (event.page.y > this.vThumb.getPosition().y) {
myInstance = this;
this.content.scrollTopNew = this.content.scrollTop.toInt() + this.content.offsetHeight.toInt();
this.scrollContent.start(0, this.content.scrollTopNew);
}
// if scrolling down
else {
myInstance = this;
this.content.scrollTopNew = this.content.scrollTop.toInt() - this.content.offsetHeight.toInt();
this.scrollContent.start(0, this.content.scrollTopNew);
}
myInstance.vUpdateThumbFromContentScroll2(event.page.y);
event.stop();
},
vStart: function(event) {
this.dragging = true;
this.vMouse.start = event.page.y;
this.vPosition.start = this.vThumb.getStyle('top').toInt();
document.addEvent('mousemove', this.bound.vDrag);
document.addEvent('mouseup', this.bound.end);
this.vThumb.addEvent('mouseup', this.bound.end);
event.stop();
},
end: function(event) {
this.dragging = false;
if (!this.inside) {
this.vScrollbar.get('tween').cancel();
this.vScrollbar.tween('width', 0);
}
document.removeEvent('mousemove', this.bound.vDrag);
document.removeEvent('mouseup', this.bound.end);
this.vThumb.removeEvent('mouseup', this.bound.end);
Blinds.updateImages();
event.stop();
},
vDrag: function(event) {
this.vMouse.now = event.page.y;
this.vPosition.now = (this.vPosition.start + (this.vMouse.now - this.vMouse.start)).limit(0, (this.vTrackSize - this.vThumbSize));
this.vUpdateContentFromThumbPosition();
this.vUpdateThumbFromContentScroll();
event.stop();
}
});
You could modify your wheel function to reset a delayed function timer (after clearing any previous timers that might still exist). To have the 'autoComplete' fired 1000ms after the last wheel event, try something like this:
wheel: function(event) {
this.content.scrollTop -= event.wheel * this.options.wheel;
this.vUpdateThumbFromContentScroll();
// clear the timer from previous wheel events, if it still exists
if(this.timer) {
clearTimeout(timer);
}
this.timer = function() {this.fireEvent('autoComplete');}.delay(1000, this);
event.stop();
},
精彩评论