/*
== malihu jquery custom scrollbars plugin ==
version: 2.8.1
author: malihu (http://manos.malihu.gr)
plugin home: http://manos.malihu.gr/jquery-custom-content-scroller
*/
/*
Copyright 2010-2013 Manos Malihutsakis
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see http://www.gnu.org/licenses/.
*/
(function ($) {
/*plugin script*/
var methods = {
init: function (options) {
var defaults = {
set_width: false, /*optional element width: boolean, pixels, percentage*/
set_height: false, /*optional element height: boolean, pixels, percentage*/
horizontalScroll: false, /*scroll horizontally: boolean*/
scrollInertia: 950, /*scrolling inertia: integer (milliseconds)*/
mouseWheel: true, /*mousewheel support: boolean*/
mouseWheelPixels: "auto", /*mousewheel pixels amount: integer, "auto"*/
autoDraggerLength: true, /*auto-adjust scrollbar dragger length: boolean*/
autoHideScrollbar: false, /*auto-hide scrollbar when idle*/
scrollButtons: {
/*scroll buttons*/
enable: false, /*scroll buttons support: boolean*/
scrollType: "continuous", /*scroll buttons scrolling type: "continuous", "pixels"*/
scrollSpeed: "auto", /*scroll buttons continuous scrolling speed: integer, "auto"*/
scrollAmount: 40 /*scroll buttons pixels scroll amount: integer (pixels)*/
},
advanced: {
updateOnBrowserResize: true, /*update scrollbars on browser resize (for layouts based on percentages): boolean*/
updateOnContentResize: false, /*auto-update scrollbars on content resize (for dynamic content): boolean*/
autoExpandHorizontalScroll: false, /*auto-expand width for horizontal scrolling: boolean*/
autoScrollOnFocus: true, /*auto-scroll on focused elements: boolean*/
normalizeMouseWheelDelta: false /*normalize mouse-wheel delta (-1/1)*/
},
contentTouchScroll: true, /*scrolling by touch-swipe content: boolean*/
callbacks: {
onScrollStart: function () {
}, /*user custom callback function on scroll start event*/
onScroll: function () {
}, /*user custom callback function on scroll event*/
onTotalScroll: function () {
}, /*user custom callback function on scroll end reached event*/
onTotalScrollBack: function () {
}, /*user custom callback function on scroll begin reached event*/
onTotalScrollOffset: 0, /*scroll end reached offset: integer (pixels)*/
onTotalScrollBackOffset: 0, /*scroll begin reached offset: integer (pixels)*/
whileScrolling: function () {
} /*user custom callback function on scrolling event*/
},
theme: "light" /*"light", "dark", "light-2", "dark-2", "light-thick", "dark-thick", "light-thin", "dark-thin"*/
},
options = $.extend(true, defaults, options);
return this.each(function () {
var $this = $(this);
/*set element width/height, create markup for custom scrollbars, add classes*/
if (options.set_width) {
$this.css("width", options.set_width);
}
if (options.set_height) {
$this.css("height", options.set_height);
}
if (!$(document).data("mCustomScrollbar-index")) {
$(document).data("mCustomScrollbar-index", "1");
} else {
var mCustomScrollbarIndex = parseInt($(document).data("mCustomScrollbar-index"));
$(document).data("mCustomScrollbar-index", mCustomScrollbarIndex + 1);
}
$this.wrapInner("
").addClass("mCustomScrollbar _mCS_" + $(document).data("mCustomScrollbar-index"));
var mCustomScrollBox = $this.children(".mCustomScrollBox");
if (options.horizontalScroll) {
mCustomScrollBox.addClass("mCSB_horizontal").wrapInner("");
var mCSB_h_wrapper = mCustomScrollBox.children(".mCSB_h_wrapper");
mCSB_h_wrapper.wrapInner("").children(".mCSB_container").css({
"width": mCSB_h_wrapper.children().outerWidth(),
"position": "relative"
}).unwrap();
} else {
mCustomScrollBox.wrapInner("");
}
var mCSB_container = mCustomScrollBox.children(".mCSB_container");
if ($.support.touch) {
mCSB_container.addClass("mCS_touch");
}
mCSB_container.after("");
var mCSB_scrollTools = mCustomScrollBox.children(".mCSB_scrollTools"),
mCSB_draggerContainer = mCSB_scrollTools.children(".mCSB_draggerContainer"),
mCSB_dragger = mCSB_draggerContainer.children(".mCSB_dragger");
if (options.horizontalScroll) {
mCSB_dragger.data("minDraggerWidth", mCSB_dragger.width());
} else {
mCSB_dragger.data("minDraggerHeight", mCSB_dragger.height());
}
if (options.scrollButtons.enable) {
if (options.horizontalScroll) {
mCSB_scrollTools.prepend("").append("");
} else {
mCSB_scrollTools.prepend("").append("");
}
}
/*mCustomScrollBox scrollTop and scrollLeft is always 0 to prevent browser focus scrolling*/
mCustomScrollBox.bind("scroll", function () {
if (!$this.is(".mCS_disabled")) { /*native focus scrolling for disabled scrollbars*/
mCustomScrollBox.scrollTop(0).scrollLeft(0);
}
});
/*store options, global vars/states, intervals*/
$this.data({
/*init state*/
"mCS_Init": true,
/*instance index*/
"mCustomScrollbarIndex": $(document).data("mCustomScrollbar-index"),
/*option parameters*/
"horizontalScroll": options.horizontalScroll,
"scrollInertia": options.scrollInertia,
"scrollEasing": "mcsEaseOut",
"mouseWheel": options.mouseWheel,
"mouseWheelPixels": options.mouseWheelPixels,
"autoDraggerLength": options.autoDraggerLength,
"autoHideScrollbar": options.autoHideScrollbar,
"scrollButtons_enable": options.scrollButtons.enable,
"scrollButtons_scrollType": options.scrollButtons.scrollType,
"scrollButtons_scrollSpeed": options.scrollButtons.scrollSpeed,
"scrollButtons_scrollAmount": options.scrollButtons.scrollAmount,
"autoExpandHorizontalScroll": options.advanced.autoExpandHorizontalScroll,
"autoScrollOnFocus": options.advanced.autoScrollOnFocus,
"normalizeMouseWheelDelta": options.advanced.normalizeMouseWheelDelta,
"contentTouchScroll": options.contentTouchScroll,
"onScrollStart_Callback": options.callbacks.onScrollStart,
"onScroll_Callback": options.callbacks.onScroll,
"onTotalScroll_Callback": options.callbacks.onTotalScroll,
"onTotalScrollBack_Callback": options.callbacks.onTotalScrollBack,
"onTotalScroll_Offset": options.callbacks.onTotalScrollOffset,
"onTotalScrollBack_Offset": options.callbacks.onTotalScrollBackOffset,
"whileScrolling_Callback": options.callbacks.whileScrolling,
/*events binding state*/
"bindEvent_scrollbar_drag": false,
"bindEvent_content_touch": false,
"bindEvent_scrollbar_click": false,
"bindEvent_mousewheel": false,
"bindEvent_buttonsContinuous_y": false,
"bindEvent_buttonsContinuous_x": false,
"bindEvent_buttonsPixels_y": false,
"bindEvent_buttonsPixels_x": false,
"bindEvent_focusin": false,
"bindEvent_autoHideScrollbar": false,
/*buttons intervals*/
"mCSB_buttonScrollRight": false,
"mCSB_buttonScrollLeft": false,
"mCSB_buttonScrollDown": false,
"mCSB_buttonScrollUp": false
});
/*max-width/max-height*/
if (options.horizontalScroll) {
if ($this.css("max-width") !== "none") {
if (!options.advanced.updateOnContentResize) { /*needs updateOnContentResize*/
options.advanced.updateOnContentResize = true;
}
}
} else {
if ($this.css("max-height") !== "none") {
var percentage = false, maxHeight = parseInt($this.css("max-height"));
if ($this.css("max-height").indexOf("%") >= 0) {
percentage = maxHeight,
maxHeight = $this.parent().height() * percentage / 100;
}
$this.css("overflow", "hidden");
mCustomScrollBox.css("max-height", maxHeight);
}
}
$this.mCustomScrollbar("update");
/*window resize fn (for layouts based on percentages)*/
if (options.advanced.updateOnBrowserResize) {
var mCSB_resizeTimeout, currWinWidth = $(window).width(), currWinHeight = $(window).height();
$(window).bind("resize." + $this.data("mCustomScrollbarIndex"), function () {
if (mCSB_resizeTimeout) {
clearTimeout(mCSB_resizeTimeout);
}
mCSB_resizeTimeout = setTimeout(function () {
if (!$this.is(".mCS_disabled") && !$this.is(".mCS_destroyed")) {
var winWidth = $(window).width(), winHeight = $(window).height();
if (currWinWidth !== winWidth || currWinHeight !== winHeight) { /*ie8 fix*/
if ($this.css("max-height") !== "none" && percentage) {
mCustomScrollBox.css("max-height", $this.parent().height() * percentage / 100);
}
$this.mCustomScrollbar("update");
currWinWidth = winWidth;
currWinHeight = winHeight;
}
}
}, 150);
});
}
/*content resize fn (for dynamically generated content)*/
if (options.advanced.updateOnContentResize) {
var mCSB_onContentResize;
if (options.horizontalScroll) {
var mCSB_containerOldSize = mCSB_container.outerWidth();
} else {
var mCSB_containerOldSize = mCSB_container.outerHeight();
}
mCSB_onContentResize = setInterval(function () {
if (options.horizontalScroll) {
if (options.advanced.autoExpandHorizontalScroll) {
mCSB_container.css({
"position": "absolute",
"width": "auto"
}).wrap("").css({
"width": mCSB_container.outerWidth(),
"position": "relative"
}).unwrap();
}
var mCSB_containerNewSize = mCSB_container.outerWidth();
} else {
var mCSB_containerNewSize = mCSB_container.outerHeight();
}
if (mCSB_containerNewSize != mCSB_containerOldSize) {
$this.mCustomScrollbar("update");
mCSB_containerOldSize = mCSB_containerNewSize;
}
}, 300);
}
});
},
update: function () {
var $this = $(this),
mCustomScrollBox = $this.children(".mCustomScrollBox"),
mCSB_container = mCustomScrollBox.children(".mCSB_container");
mCSB_container.removeClass("mCS_no_scrollbar");
$this.removeClass("mCS_disabled mCS_destroyed");
mCustomScrollBox.scrollTop(0).scrollLeft(0);
/*reset scrollTop/scrollLeft to prevent browser focus scrolling*/
var mCSB_scrollTools = mCustomScrollBox.children(".mCSB_scrollTools"),
mCSB_draggerContainer = mCSB_scrollTools.children(".mCSB_draggerContainer"),
mCSB_dragger = mCSB_draggerContainer.children(".mCSB_dragger");
if ($this.data("horizontalScroll")) {
var mCSB_buttonLeft = mCSB_scrollTools.children(".mCSB_buttonLeft"),
mCSB_buttonRight = mCSB_scrollTools.children(".mCSB_buttonRight"),
mCustomScrollBoxW = mCustomScrollBox.width();
if ($this.data("autoExpandHorizontalScroll")) {
mCSB_container.css({
"position": "absolute",
"width": "auto"
}).wrap("").css({
"width": mCSB_container.outerWidth(),
"position": "relative"
}).unwrap();
}
var mCSB_containerW = mCSB_container.outerWidth();
} else {
var mCSB_buttonUp = mCSB_scrollTools.children(".mCSB_buttonUp"),
mCSB_buttonDown = mCSB_scrollTools.children(".mCSB_buttonDown"),
mCustomScrollBoxH = mCustomScrollBox.height(),
mCSB_containerH = mCSB_container.outerHeight();
}
if (mCSB_containerH > mCustomScrollBoxH && !$this.data("horizontalScroll")) { /*content needs vertical scrolling*/
mCSB_scrollTools.css("display", "block");
var mCSB_draggerContainerH = mCSB_draggerContainer.height();
/*auto adjust scrollbar dragger length analogous to content*/
if ($this.data("autoDraggerLength")) {
var draggerH = Math.round(mCustomScrollBoxH / mCSB_containerH * mCSB_draggerContainerH),
minDraggerH = mCSB_dragger.data("minDraggerHeight");
if (draggerH <= minDraggerH) { /*min dragger height*/
mCSB_dragger.css({"height": minDraggerH});
} else if (draggerH >= mCSB_draggerContainerH - 10) { /*max dragger height*/
var mCSB_draggerContainerMaxH = mCSB_draggerContainerH - 10;
mCSB_dragger.css({"height": mCSB_draggerContainerMaxH});
} else {
mCSB_dragger.css({"height": draggerH});
}
mCSB_dragger.children(".mCSB_dragger_bar").css({"line-height": mCSB_dragger.height() + "px"});
}
var mCSB_draggerH = mCSB_dragger.height(),
/*calculate and store scroll amount, add scrolling*/
scrollAmount = (mCSB_containerH - mCustomScrollBoxH) / (mCSB_draggerContainerH - mCSB_draggerH);
$this.data("scrollAmount", scrollAmount).mCustomScrollbar("scrolling", mCustomScrollBox, mCSB_container, mCSB_draggerContainer, mCSB_dragger, mCSB_buttonUp, mCSB_buttonDown, mCSB_buttonLeft, mCSB_buttonRight);
/*scroll*/
var mCSB_containerP = Math.abs(mCSB_container.position().top);
$this.mCustomScrollbar("scrollTo", mCSB_containerP, {scrollInertia: 0, trigger: "internal"});
} else if (mCSB_containerW > mCustomScrollBoxW && $this.data("horizontalScroll")) { /*content needs horizontal scrolling*/
mCSB_scrollTools.css("display", "block");
var mCSB_draggerContainerW = mCSB_draggerContainer.width();
/*auto adjust scrollbar dragger length analogous to content*/
if ($this.data("autoDraggerLength")) {
var draggerW = Math.round(mCustomScrollBoxW / mCSB_containerW * mCSB_draggerContainerW),
minDraggerW = mCSB_dragger.data("minDraggerWidth");
if (draggerW <= minDraggerW) { /*min dragger height*/
mCSB_dragger.css({"width": minDraggerW});
} else if (draggerW >= mCSB_draggerContainerW - 10) { /*max dragger height*/
var mCSB_draggerContainerMaxW = mCSB_draggerContainerW - 10;
mCSB_dragger.css({"width": mCSB_draggerContainerMaxW});
} else {
mCSB_dragger.css({"width": draggerW});
}
}
var mCSB_draggerW = mCSB_dragger.width(),
/*calculate and store scroll amount, add scrolling*/
scrollAmount = (mCSB_containerW - mCustomScrollBoxW) / (mCSB_draggerContainerW - mCSB_draggerW);
$this.data("scrollAmount", scrollAmount).mCustomScrollbar("scrolling", mCustomScrollBox, mCSB_container, mCSB_draggerContainer, mCSB_dragger, mCSB_buttonUp, mCSB_buttonDown, mCSB_buttonLeft, mCSB_buttonRight);
/*scroll*/
var mCSB_containerP = Math.abs(mCSB_container.position().left);
$this.mCustomScrollbar("scrollTo", mCSB_containerP, {scrollInertia: 0, trigger: "internal"});
} else { /*content does not need scrolling*/
/*unbind events, reset content position, hide scrollbars, remove classes*/
mCustomScrollBox.unbind("mousewheel focusin");
if ($this.data("horizontalScroll")) {
mCSB_dragger.add(mCSB_container).css("left", 0);
} else {
mCSB_dragger.add(mCSB_container).css("top", 0);
}
mCSB_scrollTools.css("display", "none");
mCSB_container.addClass("mCS_no_scrollbar");
$this.data({"bindEvent_mousewheel": false, "bindEvent_focusin": false});
}
},
scrolling: function (mCustomScrollBox, mCSB_container, mCSB_draggerContainer, mCSB_dragger, mCSB_buttonUp, mCSB_buttonDown, mCSB_buttonLeft, mCSB_buttonRight) {
var $this = $(this);
/*scrollbar drag scrolling*/
if (!$this.data("bindEvent_scrollbar_drag")) {
var mCSB_draggerDragY, mCSB_draggerDragX;
if ($.support.msPointer) { /*MSPointer*/
mCSB_dragger.bind("MSPointerDown", function (e) {
e.preventDefault();
$this.data({"on_drag": true});
mCSB_dragger.addClass("mCSB_dragger_onDrag");
var elem = $(this),
elemOffset = elem.offset(),
x = e.originalEvent.pageX - elemOffset.left,
y = e.originalEvent.pageY - elemOffset.top;
if (x < elem.width() && x > 0 && y < elem.height() && y > 0) {
mCSB_draggerDragY = y;
mCSB_draggerDragX = x;
}
});
$(document).bind("MSPointerMove." + $this.data("mCustomScrollbarIndex"), function (e) {
e.preventDefault();
if ($this.data("on_drag")) {
var elem = mCSB_dragger,
elemOffset = elem.offset(),
x = e.originalEvent.pageX - elemOffset.left,
y = e.originalEvent.pageY - elemOffset.top;
scrollbarDrag(mCSB_draggerDragY, mCSB_draggerDragX, y, x);
}
}).bind("MSPointerUp." + $this.data("mCustomScrollbarIndex"), function (e) {
$this.data({"on_drag": false});
mCSB_dragger.removeClass("mCSB_dragger_onDrag");
});
} else { /*mouse/touch*/
mCSB_dragger.bind("mousedown touchstart", function (e) {
e.preventDefault();
e.stopImmediatePropagation();
var elem = $(this), elemOffset = elem.offset(), x, y;
if (e.type === "touchstart") {
var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0];
x = touch.pageX - elemOffset.left;
y = touch.pageY - elemOffset.top;
} else {
$this.data({"on_drag": true});
mCSB_dragger.addClass("mCSB_dragger_onDrag");
x = e.pageX - elemOffset.left;
y = e.pageY - elemOffset.top;
}
if (x < elem.width() && x > 0 && y < elem.height() && y > 0) {
mCSB_draggerDragY = y;
mCSB_draggerDragX = x;
}
}).bind("touchmove", function (e) {
e.preventDefault();
e.stopImmediatePropagation();
var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0],
elem = $(this),
elemOffset = elem.offset(),
x = touch.pageX - elemOffset.left,
y = touch.pageY - elemOffset.top;
scrollbarDrag(mCSB_draggerDragY, mCSB_draggerDragX, y, x);
});
$(document).bind("mousemove." + $this.data("mCustomScrollbarIndex"), function (e) {
if ($this.data("on_drag")) {
var elem = mCSB_dragger,
elemOffset = elem.offset(),
x = e.pageX - elemOffset.left,
y = e.pageY - elemOffset.top;
scrollbarDrag(mCSB_draggerDragY, mCSB_draggerDragX, y, x);
}
}).bind("mouseup." + $this.data("mCustomScrollbarIndex"), function (e) {
$this.data({"on_drag": false});
mCSB_dragger.removeClass("mCSB_dragger_onDrag");
});
}
$this.data({"bindEvent_scrollbar_drag": true});
}
function scrollbarDrag(mCSB_draggerDragY, mCSB_draggerDragX, y, x) {
if ($this.data("horizontalScroll")) {
$this.mCustomScrollbar("scrollTo", (mCSB_dragger.position().left - (mCSB_draggerDragX)) + x, {
moveDragger: true,
trigger: "internal"
});
} else {
$this.mCustomScrollbar("scrollTo", (mCSB_dragger.position().top - (mCSB_draggerDragY)) + y, {
moveDragger: true,
trigger: "internal"
});
}
}
/*content touch-drag*/
if ($.support.touch && $this.data("contentTouchScroll")) {
if (!$this.data("bindEvent_content_touch")) {
var touch,
elem, elemOffset, y, x, mCSB_containerTouchY, mCSB_containerTouchX;
mCSB_container.bind("touchstart", function (e) {
e.stopImmediatePropagation();
touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0];
elem = $(this);
elemOffset = elem.offset();
x = touch.pageX - elemOffset.left;
y = touch.pageY - elemOffset.top;
mCSB_containerTouchY = y;
mCSB_containerTouchX = x;
});
mCSB_container.bind("touchmove", function (e) {
e.preventDefault();
e.stopImmediatePropagation();
touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0];
elem = $(this).parent();
elemOffset = elem.offset();
x = touch.pageX - elemOffset.left;
y = touch.pageY - elemOffset.top;
if ($this.data("horizontalScroll")) {
$this.mCustomScrollbar("scrollTo", mCSB_containerTouchX - x, {trigger: "internal"});
} else {
$this.mCustomScrollbar("scrollTo", mCSB_containerTouchY - y, {trigger: "internal"});
}
});
}
}
/*dragger rail click scrolling*/
if (!$this.data("bindEvent_scrollbar_click")) {
mCSB_draggerContainer.bind("click", function (e) {
var scrollToPos = (e.pageY - mCSB_draggerContainer.offset().top) * $this.data("scrollAmount"), target = $(e.target);
if ($this.data("horizontalScroll")) {
scrollToPos = (e.pageX - mCSB_draggerContainer.offset().left) * $this.data("scrollAmount");
}
if (target.hasClass("mCSB_draggerContainer") || target.hasClass("mCSB_draggerRail")) {
$this.mCustomScrollbar("scrollTo", scrollToPos, {trigger: "internal", scrollEasing: "draggerRailEase"});
}
});
$this.data({"bindEvent_scrollbar_click": true});
}
/*mousewheel scrolling*/
if ($this.data("mouseWheel")) {
if (!$this.data("bindEvent_mousewheel")) {
mCustomScrollBox.bind("mousewheel", function (e, delta) {
var scrollTo, mouseWheelPixels = $this.data("mouseWheelPixels"), absPos = Math.abs(mCSB_container.position().top),
draggerPos = mCSB_dragger.position().top, limit = mCSB_draggerContainer.height() - mCSB_dragger.height();
if ($this.data("normalizeMouseWheelDelta")) {
if (delta < 0) {
delta = -1;
} else {
delta = 1;
}
}
if (mouseWheelPixels === "auto") {
mouseWheelPixels = 100 + Math.round($this.data("scrollAmount") / 2);
}
if ($this.data("horizontalScroll")) {
draggerPos = mCSB_dragger.position().left;
limit = mCSB_draggerContainer.width() - mCSB_dragger.width();
absPos = Math.abs(mCSB_container.position().left);
}
if ((delta > 0 && draggerPos !== 0) || (delta < 0 && draggerPos !== limit)) {
e.preventDefault();
e.stopImmediatePropagation();
}
scrollTo = absPos - (delta * mouseWheelPixels);
$this.mCustomScrollbar("scrollTo", scrollTo, {trigger: "internal"});
});
$this.data({"bindEvent_mousewheel": true});
}
}
/*buttons scrolling*/
if ($this.data("scrollButtons_enable")) {
if ($this.data("scrollButtons_scrollType") === "pixels") { /*scroll by pixels*/
if ($this.data("horizontalScroll")) {
mCSB_buttonRight.add(mCSB_buttonLeft).unbind("mousedown touchstart MSPointerDown mouseup MSPointerUp mouseout MSPointerOut touchend", mCSB_buttonRight_stop, mCSB_buttonLeft_stop);
$this.data({"bindEvent_buttonsContinuous_x": false});
if (!$this.data("bindEvent_buttonsPixels_x")) {
/*scroll right*/
mCSB_buttonRight.bind("click", function (e) {
e.preventDefault();
PixelsScrollTo(Math.abs(mCSB_container.position().left) + $this.data("scrollButtons_scrollAmount"));
});
/*scroll left*/
mCSB_buttonLeft.bind("click", function (e) {
e.preventDefault();
PixelsScrollTo(Math.abs(mCSB_container.position().left) - $this.data("scrollButtons_scrollAmount"));
});
$this.data({"bindEvent_buttonsPixels_x": true});
}
} else {
mCSB_buttonDown.add(mCSB_buttonUp).unbind("mousedown touchstart MSPointerDown mouseup MSPointerUp mouseout MSPointerOut touchend", mCSB_buttonRight_stop, mCSB_buttonLeft_stop);
$this.data({"bindEvent_buttonsContinuous_y": false});
if (!$this.data("bindEvent_buttonsPixels_y")) {
/*scroll down*/
mCSB_buttonDown.bind("click", function (e) {
e.preventDefault();
PixelsScrollTo(Math.abs(mCSB_container.position().top) + $this.data("scrollButtons_scrollAmount"));
});
/*scroll up*/
mCSB_buttonUp.bind("click", function (e) {
e.preventDefault();
PixelsScrollTo(Math.abs(mCSB_container.position().top) - $this.data("scrollButtons_scrollAmount"));
});
$this.data({"bindEvent_buttonsPixels_y": true});
}
}
function PixelsScrollTo(to) {
if (!mCSB_dragger.data("preventAction")) {
mCSB_dragger.data("preventAction", true);
$this.mCustomScrollbar("scrollTo", to, {trigger: "internal"});
}
}
} else { /*continuous scrolling*/
if ($this.data("horizontalScroll")) {
mCSB_buttonRight.add(mCSB_buttonLeft).unbind("click");
$this.data({"bindEvent_buttonsPixels_x": false});
if (!$this.data("bindEvent_buttonsContinuous_x")) {
/*scroll right*/
mCSB_buttonRight.bind("mousedown touchstart MSPointerDown", function (e) {
e.preventDefault();
var scrollButtonsSpeed = ScrollButtonsSpeed();
$this.data({
"mCSB_buttonScrollRight": setInterval(function () {
$this.mCustomScrollbar("scrollTo", Math.abs(mCSB_container.position().left) + scrollButtonsSpeed, {
trigger: "internal",
scrollEasing: "easeOutCirc"
});
}, 17)
});
});
var mCSB_buttonRight_stop = function (e) {
e.preventDefault();
clearInterval($this.data("mCSB_buttonScrollRight"));
}
mCSB_buttonRight.bind("mouseup touchend MSPointerUp mouseout MSPointerOut", mCSB_buttonRight_stop);
/*scroll left*/
mCSB_buttonLeft.bind("mousedown touchstart MSPointerDown", function (e) {
e.preventDefault();
var scrollButtonsSpeed = ScrollButtonsSpeed();
$this.data({
"mCSB_buttonScrollLeft": setInterval(function () {
$this.mCustomScrollbar("scrollTo", Math.abs(mCSB_container.position().left) - scrollButtonsSpeed, {
trigger: "internal",
scrollEasing: "easeOutCirc"
});
}, 17)
});
});
var mCSB_buttonLeft_stop = function (e) {
e.preventDefault();
clearInterval($this.data("mCSB_buttonScrollLeft"));
}
mCSB_buttonLeft.bind("mouseup touchend MSPointerUp mouseout MSPointerOut", mCSB_buttonLeft_stop);
$this.data({"bindEvent_buttonsContinuous_x": true});
}
} else {
mCSB_buttonDown.add(mCSB_buttonUp).unbind("click");
$this.data({"bindEvent_buttonsPixels_y": false});
if (!$this.data("bindEvent_buttonsContinuous_y")) {
/*scroll down*/
mCSB_buttonDown.bind("mousedown touchstart MSPointerDown", function (e) {
e.preventDefault();
var scrollButtonsSpeed = ScrollButtonsSpeed();
$this.data({
"mCSB_buttonScrollDown": setInterval(function () {
$this.mCustomScrollbar("scrollTo", Math.abs(mCSB_container.position().top) + scrollButtonsSpeed, {
trigger: "internal",
scrollEasing: "easeOutCirc"
});
}, 17)
});
});
var mCSB_buttonDown_stop = function (e) {
e.preventDefault();
clearInterval($this.data("mCSB_buttonScrollDown"));
}
mCSB_buttonDown.bind("mouseup touchend MSPointerUp mouseout MSPointerOut", mCSB_buttonDown_stop);
/*scroll up*/
mCSB_buttonUp.bind("mousedown touchstart MSPointerDown", function (e) {
e.preventDefault();
var scrollButtonsSpeed = ScrollButtonsSpeed();
$this.data({
"mCSB_buttonScrollUp": setInterval(function () {
$this.mCustomScrollbar("scrollTo", Math.abs(mCSB_container.position().top) - scrollButtonsSpeed, {
trigger: "internal",
scrollEasing: "easeOutCirc"
});
}, 17)
});
});
var mCSB_buttonUp_stop = function (e) {
e.preventDefault();
clearInterval($this.data("mCSB_buttonScrollUp"));
}
mCSB_buttonUp.bind("mouseup touchend MSPointerUp mouseout MSPointerOut", mCSB_buttonUp_stop);
$this.data({"bindEvent_buttonsContinuous_y": true});
}
}
function ScrollButtonsSpeed() {
var speed = $this.data("scrollButtons_scrollSpeed");
if ($this.data("scrollButtons_scrollSpeed") === "auto") {
speed = Math.round(($this.data("scrollInertia") + 100) / 40);
}
return speed;
}
}
}
/*scrolling on element focus (e.g. via TAB key)*/
if ($this.data("autoScrollOnFocus")) {
if (!$this.data("bindEvent_focusin")) {
mCustomScrollBox.bind("focusin", function () {
mCustomScrollBox.scrollTop(0).scrollLeft(0);
var focusedElem = $(document.activeElement);
if (focusedElem.is("input,textarea,select,button,a[tabindex],area,object")) {
var mCSB_containerPos = mCSB_container.position().top,
focusedElemPos = focusedElem.position().top,
visibleLimit = mCustomScrollBox.height() - focusedElem.outerHeight();
if ($this.data("horizontalScroll")) {
mCSB_containerPos = mCSB_container.position().left;
focusedElemPos = focusedElem.position().left;
visibleLimit = mCustomScrollBox.width() - focusedElem.outerWidth();
}
if (mCSB_containerPos + focusedElemPos < 0 || mCSB_containerPos + focusedElemPos > visibleLimit) {
$this.mCustomScrollbar("scrollTo", focusedElemPos, {trigger: "internal"});
}
}
});
$this.data({"bindEvent_focusin": true});
}
}
/*auto-hide scrollbar*/
if ($this.data("autoHideScrollbar")) {
if (!$this.data("bindEvent_autoHideScrollbar")) {
mCustomScrollBox.bind("mouseenter", function (e) {
mCustomScrollBox.addClass("mCS-mouse-over");
functions.showScrollbar.call(mCustomScrollBox.children(".mCSB_scrollTools"));
}).bind("mouseleave touchend", function (e) {
mCustomScrollBox.removeClass("mCS-mouse-over");
if (e.type === "mouseleave") {
functions.hideScrollbar.call(mCustomScrollBox.children(".mCSB_scrollTools"));
}
});
$this.data({"bindEvent_autoHideScrollbar": true});
}
}
},
scrollTo: function (scrollTo, options) {
var $this = $(this),
defaults = {
moveDragger: false,
trigger: "external",
callbacks: true,
scrollInertia: $this.data("scrollInertia"),
scrollEasing: $this.data("scrollEasing")
},
options = $.extend(defaults, options),
draggerScrollTo,
mCustomScrollBox = $this.children(".mCustomScrollBox"),
mCSB_container = mCustomScrollBox.children(".mCSB_container"),
mCSB_scrollTools = mCustomScrollBox.children(".mCSB_scrollTools"),
mCSB_draggerContainer = mCSB_scrollTools.children(".mCSB_draggerContainer"),
mCSB_dragger = mCSB_draggerContainer.children(".mCSB_dragger"),
contentSpeed = draggerSpeed = options.scrollInertia,
scrollBeginning, scrollBeginningOffset, totalScroll, totalScrollOffset;
if (!mCSB_container.hasClass("mCS_no_scrollbar")) {
$this.data({"mCS_trigger": options.trigger});
if ($this.data("mCS_Init")) {
options.callbacks = false;
}
if (scrollTo || scrollTo === 0) {
if (typeof(scrollTo) === "number") { /*if integer, scroll by number of pixels*/
if (options.moveDragger) { /*scroll dragger*/
draggerScrollTo = scrollTo;
if ($this.data("horizontalScroll")) {
scrollTo = mCSB_dragger.position().left * $this.data("scrollAmount");
} else {
scrollTo = mCSB_dragger.position().top * $this.data("scrollAmount");
}
draggerSpeed = 0;
} else { /*scroll content by default*/
draggerScrollTo = scrollTo / $this.data("scrollAmount");
}
} else if (typeof(scrollTo) === "string") { /*if string, scroll by element position*/
var target;
if (scrollTo === "top") { /*scroll to top*/
target = 0;
} else if (scrollTo === "bottom" && !$this.data("horizontalScroll")) { /*scroll to bottom*/
target = mCSB_container.outerHeight() - mCustomScrollBox.height();
} else if (scrollTo === "left") { /*scroll to left*/
target = 0;
} else if (scrollTo === "right" && $this.data("horizontalScroll")) { /*scroll to right*/
target = mCSB_container.outerWidth() - mCustomScrollBox.width();
} else if (scrollTo === "first") { /*scroll to first element position*/
target = $this.find(".mCSB_container").find(":first");
} else if (scrollTo === "last") { /*scroll to last element position*/
target = $this.find(".mCSB_container").find(":last");
} else { /*scroll to element position*/
target = $this.find(scrollTo);
}
if (target.length === 1) { /*if such unique element exists, scroll to it*/
if ($this.data("horizontalScroll")) {
scrollTo = target.position().left;
} else {
scrollTo = target.position().top;
}
draggerScrollTo = scrollTo / $this.data("scrollAmount");
} else {
draggerScrollTo = scrollTo = target;
}
}
/*scroll to*/
if ($this.data("horizontalScroll")) {
if ($this.data("onTotalScrollBack_Offset")) { /*scroll beginning offset*/
scrollBeginningOffset = -$this.data("onTotalScrollBack_Offset");
}
if ($this.data("onTotalScroll_Offset")) { /*total scroll offset*/
totalScrollOffset = mCustomScrollBox.width() - mCSB_container.outerWidth() + $this.data("onTotalScroll_Offset");
}
if (draggerScrollTo < 0) { /*scroll start position*/
draggerScrollTo = scrollTo = 0;
clearInterval($this.data("mCSB_buttonScrollLeft"));
if (!scrollBeginningOffset) {
scrollBeginning = true;
}
} else if (draggerScrollTo >= mCSB_draggerContainer.width() - mCSB_dragger.width()) { /*scroll end position*/
draggerScrollTo = mCSB_draggerContainer.width() - mCSB_dragger.width();
scrollTo = mCustomScrollBox.width() - mCSB_container.outerWidth();
clearInterval($this.data("mCSB_buttonScrollRight"));
if (!totalScrollOffset) {
totalScroll = true;
}
} else {
scrollTo = -scrollTo;
}
/*scrolling animation*/
functions.mTweenAxis.call(this, mCSB_dragger[0], "left", Math.round(draggerScrollTo), draggerSpeed, options.scrollEasing);
functions.mTweenAxis.call(this, mCSB_container[0], "left", Math.round(scrollTo), contentSpeed, options.scrollEasing, {
onStart: function () {
if (options.callbacks && !$this.data("mCS_tweenRunning")) {
callbacks("onScrollStart");
}
if ($this.data("autoHideScrollbar")) {
functions.showScrollbar.call(mCSB_scrollTools);
}
},
onUpdate: function () {
if (options.callbacks) {
callbacks("whileScrolling");
}
},
onComplete: function () {
if (options.callbacks) {
callbacks("onScroll");
if (scrollBeginning || (scrollBeginningOffset && mCSB_container.position().left >= scrollBeginningOffset)) {
callbacks("onTotalScrollBack");
}
if (totalScroll || (totalScrollOffset && mCSB_container.position().left <= totalScrollOffset)) {
callbacks("onTotalScroll");
}
}
mCSB_dragger.data("preventAction", false);
$this.data("mCS_tweenRunning", false);
if ($this.data("autoHideScrollbar")) {
if (!mCustomScrollBox.hasClass("mCS-mouse-over")) {
functions.hideScrollbar.call(mCSB_scrollTools);
}
}
}
});
} else {
if ($this.data("onTotalScrollBack_Offset")) { /*scroll beginning offset*/
scrollBeginningOffset = -$this.data("onTotalScrollBack_Offset");
}
if ($this.data("onTotalScroll_Offset")) { /*total scroll offset*/
totalScrollOffset = mCustomScrollBox.height() - mCSB_container.outerHeight() + $this.data("onTotalScroll_Offset");
}
if (draggerScrollTo < 0) { /*scroll start position*/
draggerScrollTo = scrollTo = 0;
clearInterval($this.data("mCSB_buttonScrollUp"));
if (!scrollBeginningOffset) {
scrollBeginning = true;
}
} else if (draggerScrollTo >= mCSB_draggerContainer.height() - mCSB_dragger.height()) { /*scroll end position*/
draggerScrollTo = mCSB_draggerContainer.height() - mCSB_dragger.height();
scrollTo = mCustomScrollBox.height() - mCSB_container.outerHeight();
clearInterval($this.data("mCSB_buttonScrollDown"));
if (!totalScrollOffset) {
totalScroll = true;
}
} else {
scrollTo = -scrollTo;
}
/*scrolling animation*/
functions.mTweenAxis.call(this, mCSB_dragger[0], "top", Math.round(draggerScrollTo), draggerSpeed, options.scrollEasing);
functions.mTweenAxis.call(this, mCSB_container[0], "top", Math.round(scrollTo), contentSpeed, options.scrollEasing, {
onStart: function () {
if (options.callbacks && !$this.data("mCS_tweenRunning")) {
callbacks("onScrollStart");
}
if ($this.data("autoHideScrollbar")) {
functions.showScrollbar.call(mCSB_scrollTools);
}
},
onUpdate: function () {
if (options.callbacks) {
callbacks("whileScrolling");
}
},
onComplete: function () {
if (options.callbacks) {
callbacks("onScroll");
if (scrollBeginning || (scrollBeginningOffset && mCSB_container.position().top >= scrollBeginningOffset)) {
callbacks("onTotalScrollBack");
}
if (totalScroll || (totalScrollOffset && mCSB_container.position().top <= totalScrollOffset)) {
callbacks("onTotalScroll");
}
}
mCSB_dragger.data("preventAction", false);
$this.data("mCS_tweenRunning", false);
if ($this.data("autoHideScrollbar")) {
if (!mCustomScrollBox.hasClass("mCS-mouse-over")) {
functions.hideScrollbar.call(mCSB_scrollTools);
}
}
}
});
}
if ($this.data("mCS_Init")) {
$this.data({"mCS_Init": false});
}
}
}
/*callbacks*/
function callbacks(cb) {
this.mcs = {
top: mCSB_container.position().top, left: mCSB_container.position().left,
draggerTop: mCSB_dragger.position().top, draggerLeft: mCSB_dragger.position().left,
topPct: Math.round((100 * Math.abs(mCSB_container.position().top)) / Math.abs(mCSB_container.outerHeight() - mCustomScrollBox.height())),
leftPct: Math.round((100 * Math.abs(mCSB_container.position().left)) / Math.abs(mCSB_container.outerWidth() - mCustomScrollBox.width()))
};
switch (cb) {
/*start scrolling callback*/
case "onScrollStart":
$this.data("mCS_tweenRunning", true).data("onScrollStart_Callback").call($this, this.mcs);
break;
case "whileScrolling":
$this.data("whileScrolling_Callback").call($this, this.mcs);
break;
case "onScroll":
$this.data("onScroll_Callback").call($this, this.mcs);
break;
case "onTotalScrollBack":
$this.data("onTotalScrollBack_Callback").call($this, this.mcs);
break;
case "onTotalScroll":
$this.data("onTotalScroll_Callback").call($this, this.mcs);
break;
}
}
},
stop: function () {
var $this = $(this),
mCSB_container = $this.children().children(".mCSB_container"),
mCSB_dragger = $this.children().children().children().children(".mCSB_dragger");
functions.mTweenAxisStop.call(this, mCSB_container[0]);
functions.mTweenAxisStop.call(this, mCSB_dragger[0]);
},
disable: function (resetScroll) {
var $this = $(this),
mCustomScrollBox = $this.children(".mCustomScrollBox"),
mCSB_container = mCustomScrollBox.children(".mCSB_container"),
mCSB_scrollTools = mCustomScrollBox.children(".mCSB_scrollTools"),
mCSB_dragger = mCSB_scrollTools.children().children(".mCSB_dragger");
mCustomScrollBox.unbind("mousewheel focusin mouseenter mouseleave touchend");
mCSB_container.unbind("touchstart touchmove")
if (resetScroll) {
if ($this.data("horizontalScroll")) {
mCSB_dragger.add(mCSB_container).css("left", 0);
} else {
mCSB_dragger.add(mCSB_container).css("top", 0);
}
}
mCSB_scrollTools.css("display", "none");
mCSB_container.addClass("mCS_no_scrollbar");
$this.data({
"bindEvent_mousewheel": false,
"bindEvent_focusin": false,
"bindEvent_content_touch": false,
"bindEvent_autoHideScrollbar": false
}).addClass("mCS_disabled");
},
destroy: function () {
var $this = $(this);
$this.removeClass("mCustomScrollbar _mCS_" + $this.data("mCustomScrollbarIndex")).addClass("mCS_destroyed").children().children(".mCSB_container").unwrap().children().unwrap().siblings(".mCSB_scrollTools").remove();
$(document).unbind("mousemove." + $this.data("mCustomScrollbarIndex") + " mouseup." + $this.data("mCustomScrollbarIndex") + " MSPointerMove." + $this.data("mCustomScrollbarIndex") + " MSPointerUp." + $this.data("mCustomScrollbarIndex"));
$(window).unbind("resize." + $this.data("mCustomScrollbarIndex"));
}
},
functions = {
/*hide/show scrollbar*/
showScrollbar: function () {
this.stop().animate({opacity: 1}, "fast");
},
hideScrollbar: function () {
this.stop().animate({opacity: 0}, "fast");
},
/*js animation tween*/
mTweenAxis: function (el, prop, to, duration, easing, callbacks) {
var callbacks = callbacks || {},
onStart = callbacks.onStart || function () {
}, onUpdate = callbacks.onUpdate || function () {
}, onComplete = callbacks.onComplete || function () {
};
var startTime = _getTime(), _delay, progress = 0, from = el.offsetTop, elStyle = el.style;
if (prop === "left") {
from = el.offsetLeft;
}
var diff = to - from;
_cancelTween();
_startTween();
function _getTime() {
if (window.performance && window.performance.now) {
return window.performance.now();
} else {
if (window.performance && window.performance.webkitNow) {
return window.performance.webkitNow();
} else {
if (Date.now) {
return Date.now();
} else {
return new Date().getTime();
}
}
}
}
function _step() {
if (!progress) {
onStart.call();
}
progress = _getTime() - startTime;
_tween();
if (progress >= el._time) {
el._time = (progress > el._time) ? progress + _delay - (progress - el._time) : progress + _delay - 1;
if (el._time < progress + 1) {
el._time = progress + 1;
}
}
if (el._time < duration) {
el._id = _request(_step);
} else {
onComplete.call();
}
}
function _tween() {
if (duration > 0) {
el.currVal = _ease(el._time, from, diff, duration, easing);
elStyle[prop] = Math.round(el.currVal) + "px";
} else {
elStyle[prop] = to + "px";
}
onUpdate.call();
}
function _startTween() {
_delay = 1000 / 60;
el._time = progress + _delay;
_request = (!window.requestAnimationFrame) ? function (f) {
_tween();
return setTimeout(f, 0.01);
} : window.requestAnimationFrame;
el._id = _request(_step);
}
function _cancelTween() {
if (el._id == null) {
return;
}
if (!window.requestAnimationFrame) {
clearTimeout(el._id);
} else {
window.cancelAnimationFrame(el._id);
}
el._id = null;
}
function _ease(t, b, c, d, type) {
switch (type) {
case "linear":
return c * t / d + b;
break;
case "easeOutQuad":
t /= d;
return -c * t * (t - 2) + b;
break;
case "easeInOutQuad":
t /= d / 2;
if (t < 1) return c / 2 * t * t + b;
t--;
return -c / 2 * (t * (t - 2) - 1) + b;
break;
case "easeOutCubic":
t /= d;
t--;
return c * (t * t * t + 1) + b;
break;
case "easeOutQuart":
t /= d;
t--;
return -c * (t * t * t * t - 1) + b;
break;
case "easeOutQuint":
t /= d;
t--;
return c * (t * t * t * t * t + 1) + b;
break;
case "easeOutCirc":
t /= d;
t--;
return c * Math.sqrt(1 - t * t) + b;
break;
case "easeOutSine":
return c * Math.sin(t / d * (Math.PI / 2)) + b;
break;
case "easeOutExpo":
return c * ( -Math.pow(2, -10 * t / d) + 1 ) + b;
break;
case "mcsEaseOut":
var ts = (t /= d) * t, tc = ts * t;
return b + c * (0.499999999999997 * tc * ts + -2.5 * ts * ts + 5.5 * tc + -6.5 * ts + 4 * t);
break;
case "draggerRailEase":
t /= d / 2;
if (t < 1) return c / 2 * t * t * t + b;
t -= 2;
return c / 2 * (t * t * t + 2) + b;
break;
}
}
},
/*stop js animation tweens*/
mTweenAxisStop: function (el) {
if (el._id == null) {
return;
}
if (!window.requestAnimationFrame) {
clearTimeout(el._id);
} else {
window.cancelAnimationFrame(el._id);
}
el._id = null;
},
/*detect requestAnimationFrame and polyfill*/
rafPolyfill: function () {
var pfx = ["ms", "moz", "webkit", "o"], i = pfx.length;
while (--i > -1 && !window.requestAnimationFrame) {
window.requestAnimationFrame = window[pfx[i] + "RequestAnimationFrame"];
window.cancelAnimationFrame = window[pfx[i] + "CancelAnimationFrame"] || window[pfx[i] + "CancelRequestAnimationFrame"];
}
}
}
/*detect features*/
functions.rafPolyfill.call();
/*requestAnimationFrame*/
$.support.touch = !!('ontouchstart' in window);
/*touch*/
$.support.msPointer = window.navigator.msPointerEnabled;
/*MSPointer support*/
/*plugin dependencies*/
var _dlp = ("https:" == document.location.protocol) ? "https:" : "http:";
$.event.special.mousewheel || document.write('