799 lines
23 KiB
JavaScript
799 lines
23 KiB
JavaScript
(function ($) {
|
|
$.fn.customScrollbar = function (options, args) {
|
|
var defaultOptions = {
|
|
skin: undefined,
|
|
hScroll: true,
|
|
vScroll: true,
|
|
updateOnWindowResize: false,
|
|
animationSpeed: 300,
|
|
onCustomScroll: undefined,
|
|
swipeSpeed: 1,
|
|
wheelSpeed: 40,
|
|
fixedThumbWidth: undefined,
|
|
fixedThumbHeight: undefined,
|
|
preventDefaultScroll: false
|
|
}
|
|
|
|
var Scrollable = function (element, options) {
|
|
this.$element = $(element);
|
|
this.options = options;
|
|
this.addScrollableClass();
|
|
this.addSkinClass();
|
|
this.addScrollBarComponents();
|
|
if (this.options.vScroll)
|
|
this.vScrollbar = new Scrollbar(this, new VSizing());
|
|
if (this.options.hScroll)
|
|
this.hScrollbar = new Scrollbar(this, new HSizing());
|
|
this.$element.data("scrollable", this);
|
|
this.initKeyboardScrolling();
|
|
this.bindEvents();
|
|
}
|
|
|
|
Scrollable.prototype = {
|
|
|
|
addScrollableClass: function () {
|
|
if (!this.$element.hasClass("scrollable")) {
|
|
this.scrollableAdded = true;
|
|
this.$element.addClass("scrollable");
|
|
}
|
|
},
|
|
|
|
removeScrollableClass: function () {
|
|
if (this.scrollableAdded)
|
|
this.$element.removeClass("scrollable");
|
|
},
|
|
|
|
addSkinClass: function () {
|
|
if (typeof(this.options.skin) == "string" && !this.$element.hasClass(this.options.skin)) {
|
|
this.skinClassAdded = true;
|
|
this.$element.addClass(this.options.skin);
|
|
}
|
|
},
|
|
|
|
removeSkinClass: function () {
|
|
if (this.skinClassAdded)
|
|
this.$element.removeClass(this.options.skin);
|
|
},
|
|
|
|
addScrollBarComponents: function () {
|
|
this.assignViewPort();
|
|
if (this.$viewPort.length == 0) {
|
|
this.$element.wrapInner("<div class=\"viewport\" />");
|
|
this.assignViewPort();
|
|
this.viewPortAdded = true;
|
|
}
|
|
this.assignOverview();
|
|
if (this.$overview.length == 0) {
|
|
this.$viewPort.wrapInner("<div class=\"overview\" />");
|
|
this.assignOverview();
|
|
this.overviewAdded = true;
|
|
}
|
|
this.addScrollBar("vertical", "prepend");
|
|
this.addScrollBar("horizontal", "append");
|
|
},
|
|
|
|
removeScrollbarComponents: function () {
|
|
this.removeScrollbar("vertical");
|
|
this.removeScrollbar("horizontal");
|
|
if (this.overviewAdded)
|
|
this.$element.unwrap();
|
|
if (this.viewPortAdded)
|
|
this.$element.unwrap();
|
|
},
|
|
|
|
removeScrollbar: function (orientation) {
|
|
if (this[orientation + "ScrollbarAdded"])
|
|
this.$element.find(".scroll-bar." + orientation).remove();
|
|
},
|
|
|
|
assignViewPort: function () {
|
|
this.$viewPort = this.$element.find(".viewport");
|
|
},
|
|
|
|
assignOverview: function () {
|
|
this.$overview = this.$viewPort.find(".overview");
|
|
},
|
|
|
|
addScrollBar: function (orientation, fun) {
|
|
if (this.$element.find(".scroll-bar." + orientation).length == 0) {
|
|
this.$element[fun]("<div class='scroll-bar " + orientation + "'><div class='thumb'></div></div>")
|
|
this[orientation + "ScrollbarAdded"] = true;
|
|
}
|
|
},
|
|
|
|
resize: function (keepPosition) {
|
|
if (this.vScrollbar)
|
|
this.vScrollbar.resize(keepPosition);
|
|
if (this.hScrollbar)
|
|
this.hScrollbar.resize(keepPosition);
|
|
},
|
|
|
|
scrollTo: function (element) {
|
|
if (this.vScrollbar)
|
|
this.vScrollbar.scrollToElement(element);
|
|
if (this.hScrollbar)
|
|
this.hScrollbar.scrollToElement(element);
|
|
},
|
|
|
|
scrollToXY: function (x, y) {
|
|
this.scrollToX(x);
|
|
this.scrollToY(y);
|
|
},
|
|
|
|
scrollToX: function (x) {
|
|
if (this.hScrollbar)
|
|
this.hScrollbar.scrollOverviewTo(x, true);
|
|
},
|
|
|
|
scrollToY: function (y) {
|
|
if (this.vScrollbar)
|
|
this.vScrollbar.scrollOverviewTo(y, true);
|
|
},
|
|
|
|
scrollByX: function (x) {
|
|
if (this.hScrollbar)
|
|
this.scrollToX(this.hScrollbar.overviewPosition() + x);
|
|
},
|
|
|
|
scrollByY: function (y) {
|
|
if (this.vScrollbar)
|
|
this.scrollToY(this.vScrollbar.overviewPosition() + y);
|
|
},
|
|
|
|
remove: function () {
|
|
this.removeScrollableClass();
|
|
this.removeSkinClass();
|
|
this.removeScrollbarComponents();
|
|
this.$element.data("scrollable", null);
|
|
this.removeKeyboardScrolling();
|
|
if (this.vScrollbar)
|
|
this.vScrollbar.remove();
|
|
if (this.hScrollbar)
|
|
this.hScrollbar.remove();
|
|
},
|
|
|
|
setAnimationSpeed: function (speed) {
|
|
this.options.animationSpeed = speed;
|
|
},
|
|
|
|
isInside: function (element, wrappingElement) {
|
|
var $element = $(element);
|
|
var $wrappingElement = $(wrappingElement);
|
|
var elementOffset = $element.offset();
|
|
var wrappingElementOffset = $wrappingElement.offset();
|
|
return (elementOffset.top >= wrappingElementOffset.top) && (elementOffset.left >= wrappingElementOffset.left) &&
|
|
(elementOffset.top + $element.height() <= wrappingElementOffset.top + $wrappingElement.height()) &&
|
|
(elementOffset.left + $element.width() <= wrappingElementOffset.left + $wrappingElement.width())
|
|
},
|
|
|
|
initKeyboardScrolling: function () {
|
|
var _this = this;
|
|
|
|
this.elementKeydown = function (event) {
|
|
if (document.activeElement === _this.$element[0]) {
|
|
if (_this.vScrollbar)
|
|
_this.vScrollbar.keyScroll(event);
|
|
if (_this.hScrollbar)
|
|
_this.hScrollbar.keyScroll(event);
|
|
}
|
|
}
|
|
|
|
this.$element
|
|
.attr('tabindex', '-1')
|
|
.keydown(this.elementKeydown);
|
|
},
|
|
|
|
removeKeyboardScrolling: function () {
|
|
this.$element
|
|
.removeAttr('tabindex')
|
|
.off("keydown", this.elementKeydown);
|
|
},
|
|
|
|
bindEvents: function () {
|
|
if (this.options.onCustomScroll)
|
|
this.$element.on("customScroll", this.options.onCustomScroll);
|
|
}
|
|
}
|
|
|
|
var Scrollbar = function (scrollable, sizing) {
|
|
this.scrollable = scrollable;
|
|
this.sizing = sizing
|
|
this.$scrollBar = this.sizing.scrollBar(this.scrollable.$element);
|
|
this.$thumb = this.$scrollBar.find(".thumb");
|
|
this.setScrollPosition(0, 0);
|
|
this.resize();
|
|
this.initMouseMoveScrolling();
|
|
this.initMouseWheelScrolling();
|
|
this.initTouchScrolling();
|
|
this.initMouseClickScrolling();
|
|
this.initWindowResize();
|
|
}
|
|
|
|
Scrollbar.prototype = {
|
|
|
|
resize: function (keepPosition) {
|
|
this.overviewSize = this.sizing.size(this.scrollable.$overview);
|
|
this.calculateViewPortSize();
|
|
this.sizing.size(this.scrollable.$viewPort, this.viewPortSize);
|
|
this.ratio = this.viewPortSize / this.overviewSize;
|
|
this.sizing.size(this.$scrollBar, this.viewPortSize);
|
|
this.thumbSize = this.calculateThumbSize();
|
|
this.sizing.size(this.$thumb, this.thumbSize);
|
|
this.maxThumbPosition = this.calculateMaxThumbPosition();
|
|
this.maxOverviewPosition = this.calculateMaxOverviewPosition();
|
|
this.enabled = (this.overviewSize > this.viewPortSize);
|
|
if (this.scrollPercent === undefined)
|
|
this.scrollPercent = 0.0;
|
|
if (this.enabled)
|
|
this.rescroll(keepPosition);
|
|
else
|
|
this.setScrollPosition(0, 0);
|
|
this.$scrollBar.toggle(this.enabled);
|
|
},
|
|
|
|
calculateViewPortSize: function () {
|
|
var elementSize = this.sizing.size(this.scrollable.$element);
|
|
if (elementSize > 0 && !this.maxSizeUsed) {
|
|
this.viewPortSize = elementSize;
|
|
this.maxSizeUsed = false;
|
|
}
|
|
else {
|
|
var maxSize = this.sizing.maxSize(this.scrollable.$element);
|
|
this.viewPortSize = Math.min(maxSize, this.overviewSize);
|
|
this.maxSizeUsed = true;
|
|
}
|
|
},
|
|
|
|
calculateThumbSize: function () {
|
|
var fixedSize = this.sizing.fixedThumbSize(this.scrollable.options)
|
|
var size;
|
|
if (fixedSize)
|
|
size = fixedSize;
|
|
else
|
|
size = this.ratio * this.viewPortSize
|
|
return Math.max(size, this.sizing.minSize(this.$thumb));
|
|
},
|
|
|
|
initMouseMoveScrolling: function () {
|
|
var _this = this;
|
|
this.$thumb.mousedown(function (event) {
|
|
if (_this.enabled)
|
|
_this.startMouseMoveScrolling(event);
|
|
});
|
|
this.documentMouseup = function (event) {
|
|
_this.stopMouseMoveScrolling(event);
|
|
};
|
|
$(document).mouseup(this.documentMouseup);
|
|
this.documentMousemove = function (event) {
|
|
_this.mouseMoveScroll(event);
|
|
};
|
|
$(document).mousemove(this.documentMousemove);
|
|
this.$thumb.click(function (event) {
|
|
event.stopPropagation();
|
|
});
|
|
},
|
|
|
|
removeMouseMoveScrolling: function () {
|
|
this.$thumb.off();
|
|
$(document).off("mouseup", this.documentMouseup);
|
|
$(document).off("mousemove", this.documentMousemove);
|
|
},
|
|
|
|
initMouseWheelScrolling: function () {
|
|
var _this = this;
|
|
this.scrollable.$element.mousewheel(function (event, delta, deltaX, deltaY) {
|
|
if (_this.enabled) {
|
|
var scrolled = _this.mouseWheelScroll(deltaX, deltaY);
|
|
_this.stopEventConditionally(event, scrolled);
|
|
}
|
|
});
|
|
},
|
|
|
|
removeMouseWheelScrolling: function () {
|
|
this.scrollable.$element.off("mousewheel");
|
|
},
|
|
|
|
initTouchScrolling: function () {
|
|
if (document.addEventListener) {
|
|
var _this = this;
|
|
this.elementTouchstart = function (event) {
|
|
if (_this.enabled)
|
|
_this.startTouchScrolling(event);
|
|
}
|
|
this.scrollable.$element[0].addEventListener("touchstart", this.elementTouchstart);
|
|
this.documentTouchmove = function (event) {
|
|
_this.touchScroll(event);
|
|
}
|
|
this.scrollable.$element[0].addEventListener("touchmove", this.documentTouchmove);
|
|
this.elementTouchend = function (event) {
|
|
_this.stopTouchScrolling(event);
|
|
}
|
|
this.scrollable.$element[0].addEventListener("touchend", this.elementTouchend);
|
|
}
|
|
},
|
|
|
|
removeTouchScrolling: function () {
|
|
if (document.addEventListener) {
|
|
this.scrollable.$element[0].removeEventListener("touchstart", this.elementTouchstart);
|
|
document.removeEventListener("touchmove", this.documentTouchmove);
|
|
this.scrollable.$element[0].removeEventListener("touchend", this.elementTouchend);
|
|
}
|
|
},
|
|
|
|
initMouseClickScrolling: function () {
|
|
var _this = this;
|
|
this.scrollBarClick = function (event) {
|
|
_this.mouseClickScroll(event);
|
|
};
|
|
this.$scrollBar.click(this.scrollBarClick);
|
|
},
|
|
|
|
removeMouseClickScrolling: function () {
|
|
this.$scrollBar.off("click", this.scrollBarClick);
|
|
},
|
|
|
|
initWindowResize: function () {
|
|
if (this.scrollable.options.updateOnWindowResize) {
|
|
var _this = this;
|
|
this.windowResize = function () {
|
|
_this.resize();
|
|
};
|
|
$(window).resize(this.windowResize);
|
|
}
|
|
},
|
|
|
|
removeWindowResize: function () {
|
|
$(window).off("resize", this.windowResize);
|
|
},
|
|
|
|
isKeyScrolling: function (key) {
|
|
return this.keyScrollDelta(key) != null;
|
|
},
|
|
|
|
keyScrollDelta: function (key) {
|
|
for (var scrollingKey in this.sizing.scrollingKeys)
|
|
if (scrollingKey == key)
|
|
return this.sizing.scrollingKeys[key](this.viewPortSize);
|
|
return null;
|
|
},
|
|
|
|
startMouseMoveScrolling: function (event) {
|
|
this.mouseMoveScrolling = true;
|
|
$("body").addClass("not-selectable");
|
|
this.setUnselectable($("body"), "on");
|
|
this.setScrollEvent(event);
|
|
event.preventDefault();
|
|
},
|
|
|
|
stopMouseMoveScrolling: function (event) {
|
|
this.mouseMoveScrolling = false;
|
|
$("body").removeClass("not-selectable");
|
|
this.setUnselectable($("body"), null);
|
|
},
|
|
|
|
setUnselectable: function (element, value) {
|
|
if (element.attr("unselectable") != value) {
|
|
element.attr("unselectable", value);
|
|
element.find(':not(input)').attr('unselectable', value);
|
|
}
|
|
},
|
|
|
|
mouseMoveScroll: function (event) {
|
|
if (this.mouseMoveScrolling) {
|
|
var delta = this.sizing.mouseDelta(this.scrollEvent, event);
|
|
this.scrollThumbBy(delta);
|
|
this.setScrollEvent(event);
|
|
}
|
|
},
|
|
|
|
startTouchScrolling: function (event) {
|
|
if (event.touches && event.touches.length == 1) {
|
|
this.setScrollEvent(event.touches[0]);
|
|
this.touchScrolling = true;
|
|
event.stopPropagation();
|
|
}
|
|
},
|
|
|
|
touchScroll: function (event) {
|
|
if (this.touchScrolling && event.touches && event.touches.length == 1) {
|
|
var delta = -this.sizing.mouseDelta(this.scrollEvent, event.touches[0]) * this.scrollable.options.swipeSpeed;
|
|
var scrolled = this.scrollOverviewBy(delta);
|
|
if (scrolled)
|
|
this.setScrollEvent(event.touches[0]);
|
|
this.stopEventConditionally(event, scrolled);
|
|
}
|
|
},
|
|
|
|
stopTouchScrolling: function (event) {
|
|
this.touchScrolling = false;
|
|
event.stopPropagation();
|
|
},
|
|
|
|
mouseWheelScroll: function (deltaX, deltaY) {
|
|
var delta = -this.sizing.wheelDelta(deltaX, deltaY) * this.scrollable.options.wheelSpeed;
|
|
if (delta != 0)
|
|
return this.scrollOverviewBy(delta);
|
|
},
|
|
|
|
mouseClickScroll: function (event) {
|
|
var delta = this.viewPortSize - 20;
|
|
if (event["page" + this.sizing.scrollAxis()] < this.$thumb.offset()[this.sizing.offsetComponent()])
|
|
// mouse click over thumb
|
|
delta = -delta;
|
|
this.scrollOverviewBy(delta);
|
|
},
|
|
|
|
keyScroll: function (event) {
|
|
var keyDown = event.which;
|
|
if (this.enabled && this.isKeyScrolling(keyDown)) {
|
|
var scrolled = this.scrollOverviewBy(this.keyScrollDelta(keyDown));
|
|
this.stopEventConditionally(event, scrolled);
|
|
}
|
|
},
|
|
|
|
scrollThumbBy: function (delta) {
|
|
var thumbPosition = this.thumbPosition();
|
|
thumbPosition += delta;
|
|
thumbPosition = this.positionOrMax(thumbPosition, this.maxThumbPosition);
|
|
var oldScrollPercent = this.scrollPercent;
|
|
this.scrollPercent = thumbPosition / this.maxThumbPosition;
|
|
if (oldScrollPercent != this.scrollPercent) {
|
|
var overviewPosition = (thumbPosition * this.maxOverviewPosition) / this.maxThumbPosition;
|
|
this.setScrollPosition(overviewPosition, thumbPosition);
|
|
this.triggerCustomScroll(oldScrollPercent);
|
|
return true
|
|
}
|
|
else
|
|
return false;
|
|
},
|
|
|
|
thumbPosition: function () {
|
|
return this.$thumb.position()[this.sizing.offsetComponent()];
|
|
},
|
|
|
|
scrollOverviewBy: function (delta) {
|
|
var overviewPosition = this.overviewPosition() + delta;
|
|
return this.scrollOverviewTo(overviewPosition, false);
|
|
},
|
|
|
|
overviewPosition: function () {
|
|
return -this.scrollable.$overview.position()[this.sizing.offsetComponent()];
|
|
},
|
|
|
|
scrollOverviewTo: function (overviewPosition, animate) {
|
|
overviewPosition = this.positionOrMax(overviewPosition, this.maxOverviewPosition);
|
|
var oldScrollPercent = this.scrollPercent;
|
|
this.scrollPercent = overviewPosition / this.maxOverviewPosition;
|
|
if (oldScrollPercent != this.scrollPercent) {
|
|
var thumbPosition = this.scrollPercent * this.maxThumbPosition;
|
|
if (animate)
|
|
this.setScrollPositionWithAnimation(overviewPosition, thumbPosition);
|
|
else
|
|
this.setScrollPosition(overviewPosition, thumbPosition);
|
|
this.triggerCustomScroll(oldScrollPercent);
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
},
|
|
|
|
positionOrMax: function (p, max) {
|
|
if (p < 0)
|
|
return 0;
|
|
else if (p > max)
|
|
return max;
|
|
else
|
|
return p;
|
|
},
|
|
|
|
triggerCustomScroll: function (oldScrollPercent) {
|
|
this.scrollable.$element.trigger("customScroll", {
|
|
scrollAxis: this.sizing.scrollAxis(),
|
|
direction: this.sizing.scrollDirection(oldScrollPercent, this.scrollPercent),
|
|
scrollPercent: this.scrollPercent * 100
|
|
}
|
|
);
|
|
},
|
|
|
|
rescroll: function (keepPosition) {
|
|
if (keepPosition) {
|
|
var overviewPosition = this.positionOrMax(this.overviewPosition(), this.maxOverviewPosition);
|
|
this.scrollPercent = overviewPosition / this.maxOverviewPosition;
|
|
var thumbPosition = this.scrollPercent * this.maxThumbPosition;
|
|
this.setScrollPosition(overviewPosition, thumbPosition);
|
|
}
|
|
else {
|
|
var thumbPosition = this.scrollPercent * this.maxThumbPosition;
|
|
var overviewPosition = this.scrollPercent * this.maxOverviewPosition;
|
|
this.setScrollPosition(overviewPosition, thumbPosition);
|
|
}
|
|
},
|
|
|
|
setScrollPosition: function (overviewPosition, thumbPosition) {
|
|
this.$thumb.css(this.sizing.offsetComponent(), thumbPosition + "px");
|
|
this.scrollable.$overview.css(this.sizing.offsetComponent(), -overviewPosition + "px");
|
|
},
|
|
|
|
setScrollPositionWithAnimation: function (overviewPosition, thumbPosition) {
|
|
var thumbAnimationOpts = {};
|
|
var overviewAnimationOpts = {};
|
|
thumbAnimationOpts[this.sizing.offsetComponent()] = thumbPosition + "px";
|
|
this.$thumb.animate(thumbAnimationOpts, this.scrollable.options.animationSpeed);
|
|
overviewAnimationOpts[this.sizing.offsetComponent()] = -overviewPosition + "px";
|
|
this.scrollable.$overview.animate(overviewAnimationOpts, this.scrollable.options.animationSpeed);
|
|
},
|
|
|
|
calculateMaxThumbPosition: function () {
|
|
return Math.max(0, this.sizing.size(this.$scrollBar) - this.thumbSize);
|
|
},
|
|
|
|
calculateMaxOverviewPosition: function () {
|
|
return Math.max(0, this.sizing.size(this.scrollable.$overview) - this.sizing.size(this.scrollable.$viewPort));
|
|
},
|
|
|
|
setScrollEvent: function (event) {
|
|
var attr = "page" + this.sizing.scrollAxis();
|
|
if (!this.scrollEvent || this.scrollEvent[attr] != event[attr])
|
|
this.scrollEvent = {pageX: event.pageX, pageY: event.pageY};
|
|
},
|
|
|
|
scrollToElement: function (element) {
|
|
var $element = $(element);
|
|
if (this.sizing.isInside($element, this.scrollable.$overview) && !this.sizing.isInside($element, this.scrollable.$viewPort)) {
|
|
var elementOffset = $element.offset();
|
|
var overviewOffset = this.scrollable.$overview.offset();
|
|
var viewPortOffset = this.scrollable.$viewPort.offset();
|
|
this.scrollOverviewTo(elementOffset[this.sizing.offsetComponent()] - overviewOffset[this.sizing.offsetComponent()], true);
|
|
}
|
|
},
|
|
|
|
remove: function () {
|
|
this.removeMouseMoveScrolling();
|
|
this.removeMouseWheelScrolling();
|
|
this.removeTouchScrolling();
|
|
this.removeMouseClickScrolling();
|
|
this.removeWindowResize();
|
|
},
|
|
|
|
stopEventConditionally: function (event, condition) {
|
|
if (condition || this.scrollable.options.preventDefaultScroll) {
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
}
|
|
}
|
|
}
|
|
|
|
var HSizing = function () {
|
|
}
|
|
|
|
HSizing.prototype = {
|
|
size: function ($el, arg) {
|
|
if (arg)
|
|
return $el.width(arg);
|
|
else
|
|
return $el.width();
|
|
},
|
|
|
|
minSize: function ($el) {
|
|
return parseInt($el.css("min-width")) || 0;
|
|
},
|
|
|
|
maxSize: function ($el) {
|
|
return parseInt($el.css("max-width")) || 0;
|
|
},
|
|
|
|
fixedThumbSize: function (options) {
|
|
return options.fixedThumbWidth;
|
|
},
|
|
|
|
scrollBar: function ($el) {
|
|
return $el.find(".scroll-bar.horizontal");
|
|
},
|
|
|
|
mouseDelta: function (event1, event2) {
|
|
return event2.pageX - event1.pageX;
|
|
},
|
|
|
|
offsetComponent: function () {
|
|
return "left";
|
|
},
|
|
|
|
wheelDelta: function (deltaX, deltaY) {
|
|
return deltaX;
|
|
},
|
|
|
|
scrollAxis: function () {
|
|
return "X";
|
|
},
|
|
|
|
scrollDirection: function (oldPercent, newPercent) {
|
|
return oldPercent < newPercent ? "right" : "left";
|
|
},
|
|
|
|
scrollingKeys: {
|
|
37: function (viewPortSize) {
|
|
return -10; //arrow left
|
|
},
|
|
39: function (viewPortSize) {
|
|
return 10; //arrow right
|
|
}
|
|
},
|
|
|
|
isInside: function (element, wrappingElement) {
|
|
var $element = $(element);
|
|
var $wrappingElement = $(wrappingElement);
|
|
var elementOffset = $element.offset();
|
|
var wrappingElementOffset = $wrappingElement.offset();
|
|
return (elementOffset.left >= wrappingElementOffset.left) &&
|
|
(elementOffset.left + $element.width() <= wrappingElementOffset.left + $wrappingElement.width());
|
|
}
|
|
}
|
|
|
|
var VSizing = function () {
|
|
}
|
|
|
|
VSizing.prototype = {
|
|
|
|
size: function ($el, arg) {
|
|
if (arg)
|
|
return $el.height(arg);
|
|
else
|
|
return parseInt($el.css("height")) || 0;
|
|
},
|
|
|
|
minSize: function ($el) {
|
|
return parseInt($el.css("min-height")) || 0;
|
|
},
|
|
|
|
maxSize: function ($el) {
|
|
return parseInt($el.css("max-height")) || 0;
|
|
},
|
|
|
|
fixedThumbSize: function (options) {
|
|
return options.fixedThumbHeight;
|
|
},
|
|
|
|
scrollBar: function ($el) {
|
|
return $el.find(".scroll-bar.vertical");
|
|
},
|
|
|
|
mouseDelta: function (event1, event2) {
|
|
return event2.pageY - event1.pageY;
|
|
},
|
|
|
|
offsetComponent: function () {
|
|
return "top";
|
|
},
|
|
|
|
wheelDelta: function (deltaX, deltaY) {
|
|
return deltaY;
|
|
},
|
|
|
|
scrollAxis: function () {
|
|
return "Y";
|
|
},
|
|
|
|
scrollDirection: function (oldPercent, newPercent) {
|
|
return oldPercent < newPercent ? "down" : "up";
|
|
},
|
|
|
|
scrollingKeys: {
|
|
38: function (viewPortSize) {
|
|
return -10; //arrow up
|
|
},
|
|
40: function (viewPortSize) {
|
|
return 10; //arrow down
|
|
},
|
|
33: function (viewPortSize) {
|
|
return -(viewPortSize - 20); //page up
|
|
},
|
|
34: function (viewPortSize) {
|
|
return viewPortSize - 20; //page down
|
|
}
|
|
},
|
|
|
|
isInside: function (element, wrappingElement) {
|
|
var $element = $(element);
|
|
var $wrappingElement = $(wrappingElement);
|
|
var elementOffset = $element.offset();
|
|
var wrappingElementOffset = $wrappingElement.offset();
|
|
return (elementOffset.top >= wrappingElementOffset.top) &&
|
|
(elementOffset.top + $element.height() <= wrappingElementOffset.top + $wrappingElement.height());
|
|
}
|
|
}
|
|
|
|
return this.each(function () {
|
|
if (options == undefined)
|
|
options = defaultOptions;
|
|
if (typeof(options) == "string") {
|
|
var scrollable = $(this).data("scrollable");
|
|
if (scrollable)
|
|
scrollable[options](args);
|
|
}
|
|
else if (typeof(options) == "object") {
|
|
options = $.extend(defaultOptions, options);
|
|
new Scrollable($(this), options);
|
|
}
|
|
else
|
|
throw "Invalid type of options";
|
|
});
|
|
};
|
|
})(jQuery);
|
|
|
|
(function ($) {
|
|
var types = ['DOMMouseScroll', 'mousewheel'];
|
|
|
|
if ($.event.fixHooks) {
|
|
for (var i = types.length; i;) {
|
|
$.event.fixHooks[ types[--i] ] = $.event.mouseHooks;
|
|
}
|
|
}
|
|
|
|
$.event.special.mousewheel = {
|
|
setup: function () {
|
|
if (this.addEventListener) {
|
|
for (var i = types.length; i;) {
|
|
this.addEventListener(types[--i], handler, false);
|
|
}
|
|
} else {
|
|
this.onmousewheel = handler;
|
|
}
|
|
},
|
|
|
|
teardown: function () {
|
|
if (this.removeEventListener) {
|
|
for (var i = types.length; i;) {
|
|
this.removeEventListener(types[--i], handler, false);
|
|
}
|
|
} else {
|
|
this.onmousewheel = null;
|
|
}
|
|
}
|
|
};
|
|
|
|
$.fn.extend({
|
|
mousewheel: function (fn) {
|
|
return fn ? this.on("mousewheel", fn) : this.trigger("mousewheel");
|
|
},
|
|
|
|
unmousewheel: function (fn) {
|
|
return this.off("mousewheel", fn);
|
|
}
|
|
});
|
|
|
|
function handler(event) {
|
|
var orgEvent = event || window.event, args = [].slice.call(arguments, 1), delta = 0, returnValue = true, deltaX = 0, deltaY = 0;
|
|
event = $.event.fix(orgEvent);
|
|
event.type = "mousewheel";
|
|
|
|
// Old school scrollwheel delta
|
|
if (orgEvent.wheelDelta) {
|
|
delta = orgEvent.wheelDelta / 120;
|
|
}
|
|
if (orgEvent.detail) {
|
|
delta = -orgEvent.detail / 3;
|
|
}
|
|
|
|
// New school multidimensional scroll (touchpads) deltas
|
|
deltaY = delta;
|
|
|
|
// Gecko
|
|
if (orgEvent.axis !== undefined && orgEvent.axis === orgEvent.HORIZONTAL_AXIS) {
|
|
deltaY = 0;
|
|
deltaX = delta;
|
|
}
|
|
|
|
// Webkit
|
|
if (orgEvent.wheelDeltaY !== undefined) {
|
|
deltaY = orgEvent.wheelDeltaY / 120;
|
|
}
|
|
if (orgEvent.wheelDeltaX !== undefined) {
|
|
deltaX = orgEvent.wheelDeltaX / 120;
|
|
}
|
|
|
|
// Add event and delta to the front of the arguments
|
|
args.unshift(event, delta, deltaX, deltaY);
|
|
|
|
return ($.event.dispatch || $.event.handle).apply(this, args);
|
|
}
|
|
})(jQuery);
|