1
0
Fork 0
mirror of https://github.com/lrsjng/h5ai synced 2025-12-06 08:52:45 +01:00
h5ai/src/_h5ai/client/js/lib/jquery.scrollpanel-0.1.js
2012-10-05 19:55:48 +02:00

243 lines
5.1 KiB
JavaScript

/*! jQuery.scrollpanel 0.1 - //larsjung.de/scrollpanel - MIT License */
(function ($) {
'use strict';
var $window = $(window),
name = 'scrollpanel',
defaults = {
prefix: 'sp-'
},
// Scrollpanel
// ===========
ScrollPanel = function (element, options) {
var self = this;
// Main reference.
self.$el = $(element);
self.settings = $.extend({}, defaults, options);
var prefix = self.settings.prefix;
// Mouse offset on drag start.
self.mouseOffsetY = 0;
// Interval ID for automatic scrollbar updates.
self.updateId = 0;
// Proxy to easily bind and unbind this method.
self.scrollProxy = $.proxy(self.scroll, self);
// Make content space relative, if not already.
if (!self.$el.css('position') || self.$el.css('position') === 'static') {
self.$el.css('position', 'relative');
}
// Create scrollbar.
self.$scrollbar = $('<div class="' + prefix + 'scrollbar" />');
self.$thumb = $('<div class="' + prefix + 'thumb" />').appendTo(self.$scrollbar);
// Wrap element's content and add scrollbar.
self.$el
.addClass(prefix + 'host')
.wrapInner('<div class="' + prefix + 'viewport"><div class="' + prefix + 'container" /></div>')
.append(self.$scrollbar);
// // Get references.
self.$viewport = self.$el.find('> .' + prefix + 'viewport');
self.$container = self.$viewport.find('> .' + prefix + 'container');
// Host
// ----
self.$el
// Handle mouse wheel.
.on('mousewheel', function (event, delta, deltaX, deltaY) {
self.$viewport.scrollTop(self.$viewport.scrollTop() - 50 * deltaY);
self.update();
event.preventDefault();
event.stopPropagation();
})
// Handle scrolling.
.on('scroll', function () {
self.update();
});
// Viewport
// --------
self.$viewport
// Basic styling.
.css({
paddingRight: self.$scrollbar.outerWidth(true),
height: self.$el.height(),
overflow: 'hidden'
});
// Container
// ---------
self.$container
// Basic styling.
.css({
overflow: 'hidden'
});
// Srollbar
// --------
self.$scrollbar
// Basic styling.
.css({
position: 'absolute',
top: 0,
right: 0,
overflow: 'hidden'
})
// Handle mouse buttons.
.on('mousedown', function (event) {
self.mouseOffsetY = self.$thumb.outerHeight() / 2;
self.onMousedown(event);
})
// Disable selection.
.each(function () {
self.onselectstart = function () {
return false;
};
});
// Scrollbar Thumb
// ---------------
self.$thumb
// Basic styling.
.css({
position: 'absolute',
left: 0,
width: '100%'
})
// Handle mouse buttons.
.on('mousedown', function (event) {
self.mouseOffsetY = event.pageY - self.$thumb.offset().top;
self.onMousedown(event);
});
// Initial update.
self.update();
};
// Scrollpanel methods
// ===================
$.extend(ScrollPanel.prototype, {
// Rerender scrollbar.
update: function (repeat) {
var self = this;
if (self.updateId && !repeat) {
clearInterval(self.updateId);
self.updateId = 0;
} else if (!self.updateId && repeat) {
self.updateId = setInterval(function() {
self.update(true);
}, 50);
}
self.$viewport.css('height', self.$el.height());
var visibleHeight = self.$el.height(),
contentHeight = self.$container.outerHeight(),
scrollTop = self.$viewport.scrollTop(),
scrollTopFrac = scrollTop / contentHeight,
visVertFrac = Math.min(visibleHeight / contentHeight, 1),
scrollbarHeight = self.$scrollbar.height();
if (visVertFrac < 1) {
self.$scrollbar
.css({
height: self.$el.innerHeight() + scrollbarHeight - self.$scrollbar.outerHeight(true)
})
.fadeIn(50);
self.$thumb
.css({
top: scrollbarHeight * scrollTopFrac,
height: scrollbarHeight * visVertFrac
});
} else {
self.$scrollbar.fadeOut(50);
}
},
// Scroll content according to mouse position.
scroll: function (event) {
var self = this,
clickFrac = (event.pageY - self.$scrollbar.offset().top - self.mouseOffsetY) / self.$scrollbar.height();
self.$viewport.scrollTop(self.$container.outerHeight() * clickFrac);
self.update();
event.preventDefault();
event.stopPropagation();
},
// Handle mousedown events on scrollbar.
onMousedown: function (event) {
var self = this;
self.scroll(event);
self.$scrollbar.addClass('active');
$window
.on('mousemove', self.scrollProxy)
.one('mouseup', function (event) {
self.$scrollbar.removeClass('active');
$window.off('mousemove', self.scrollProxy);
self.scroll(event);
});
}
});
// Register the plug in
// --------------------
$.fn[name] = function (options, options2) {
return this.each(function () {
var $this = $(this),
scrollpanel = $this.data(name);
if (!scrollpanel) {
scrollpanel = new ScrollPanel(this, options);
scrollpanel.update();
$this.data(name, scrollpanel);
}
if (options === 'update') {
scrollpanel.update(options2);
}
});
};
}(jQuery));