123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878 |
- /*! Copyright (c) 2013 Brandon Aaron (http://brandon.aaron.sh)
- * Licensed under the MIT License (LICENSE.txt).
- *
- * Version: 3.1.9
- *
- * Requires: jQuery 1.2.2+
- */
- (function (factory) {
- if ( typeof define === 'function' && define.amd ) {
- // AMD. Register as an anonymous module.
- define(['jquery'], factory);
- } else if (typeof exports === 'object') {
- // Node/CommonJS style for Browserify
- module.exports = factory;
- } else {
- // Browser globals
- factory(jQuery);
- }
- }(function ($) {
- var toFix = ['wheel', 'mousewheel', 'DOMMouseScroll', 'MozMousePixelScroll'],
- toBind = ( 'onwheel' in document || document.documentMode >= 9 ) ?
- ['wheel'] : ['mousewheel', 'DomMouseScroll', 'MozMousePixelScroll'],
- slice = Array.prototype.slice,
- nullLowestDeltaTimeout, lowestDelta;
- if ( $.event.fixHooks ) {
- for ( var i = toFix.length; i; ) {
- $.event.fixHooks[ toFix[--i] ] = $.event.mouseHooks;
- }
- }
- var special = $.event.special.mousewheel = {
- version: '3.1.9',
- setup: function() {
- if ( this.addEventListener ) {
- for ( var i = toBind.length; i; ) {
- this.addEventListener( toBind[--i], handler, false );
- }
- } else {
- this.onmousewheel = handler;
- }
- // Store the line height and page height for this particular element
- $.data(this, 'mousewheel-line-height', special.getLineHeight(this));
- $.data(this, 'mousewheel-page-height', special.getPageHeight(this));
- },
- teardown: function() {
- if ( this.removeEventListener ) {
- for ( var i = toBind.length; i; ) {
- this.removeEventListener( toBind[--i], handler, false );
- }
- } else {
- this.onmousewheel = null;
- }
- },
- getLineHeight: function(elem) {
- return parseInt($(elem)['offsetParent' in $.fn ? 'offsetParent' : 'parent']().css('fontSize'), 10);
- },
- getPageHeight: function(elem) {
- return $(elem).height();
- },
- settings: {
- adjustOldDeltas: true
- }
- };
- $.fn.extend({
- mousewheel: function(fn) {
- return fn ? this.bind('mousewheel', fn) : this.trigger('mousewheel');
- },
- unmousewheel: function(fn) {
- return this.unbind('mousewheel', fn);
- }
- });
- function handler(event) {
- var orgEvent = event || window.event,
- args = slice.call(arguments, 1),
- delta = 0,
- deltaX = 0,
- deltaY = 0,
- absDelta = 0;
- event = $.event.fix(orgEvent);
- event.type = 'mousewheel';
- // Old school scrollwheel delta
- if ( 'detail' in orgEvent ) { deltaY = orgEvent.detail * -1; }
- if ( 'wheelDelta' in orgEvent ) { deltaY = orgEvent.wheelDelta; }
- if ( 'wheelDeltaY' in orgEvent ) { deltaY = orgEvent.wheelDeltaY; }
- if ( 'wheelDeltaX' in orgEvent ) { deltaX = orgEvent.wheelDeltaX * -1; }
- // Firefox < 17 horizontal scrolling related to DOMMouseScroll event
- if ( 'axis' in orgEvent && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) {
- deltaX = deltaY * -1;
- deltaY = 0;
- }
- // Set delta to be deltaY or deltaX if deltaY is 0 for backwards compatabilitiy
- delta = deltaY === 0 ? deltaX : deltaY;
- // New school wheel delta (wheel event)
- if ( 'deltaY' in orgEvent ) {
- deltaY = orgEvent.deltaY * -1;
- delta = deltaY;
- }
- if ( 'deltaX' in orgEvent ) {
- deltaX = orgEvent.deltaX;
- if ( deltaY === 0 ) { delta = deltaX * -1; }
- }
- // No change actually happened, no reason to go any further
- if ( deltaY === 0 && deltaX === 0 ) { return; }
- // Need to convert lines and pages to pixels if we aren't already in pixels
- // There are three delta modes:
- // * deltaMode 0 is by pixels, nothing to do
- // * deltaMode 1 is by lines
- // * deltaMode 2 is by pages
- if ( orgEvent.deltaMode === 1 ) {
- var lineHeight = $.data(this, 'mousewheel-line-height');
- delta *= lineHeight;
- deltaY *= lineHeight;
- deltaX *= lineHeight;
- } else if ( orgEvent.deltaMode === 2 ) {
- var pageHeight = $.data(this, 'mousewheel-page-height');
- delta *= pageHeight;
- deltaY *= pageHeight;
- deltaX *= pageHeight;
- }
- // Store lowest absolute delta to normalize the delta values
- absDelta = Math.max( Math.abs(deltaY), Math.abs(deltaX) );
- if ( !lowestDelta || absDelta < lowestDelta ) {
- lowestDelta = absDelta;
- // Adjust older deltas if necessary
- if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) {
- lowestDelta /= 40;
- }
- }
- // Adjust older deltas if necessary
- if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) {
- // Divide all the things by 40!
- delta /= 40;
- deltaX /= 40;
- deltaY /= 40;
- }
- // Get a whole, normalized value for the deltas
- delta = Math[ delta >= 1 ? 'floor' : 'ceil' ](delta / lowestDelta);
- deltaX = Math[ deltaX >= 1 ? 'floor' : 'ceil' ](deltaX / lowestDelta);
- deltaY = Math[ deltaY >= 1 ? 'floor' : 'ceil' ](deltaY / lowestDelta);
- // Add information to the event object
- event.deltaX = deltaX;
- event.deltaY = deltaY;
- event.deltaFactor = lowestDelta;
- // Go ahead and set deltaMode to 0 since we converted to pixels
- // Although this is a little odd since we overwrite the deltaX/Y
- // properties with normalized deltas.
- event.deltaMode = 0;
- // Add event and delta to the front of the arguments
- args.unshift(event, delta, deltaX, deltaY);
- // Clearout lowestDelta after sometime to better
- // handle multiple device types that give different
- // a different lowestDelta
- // Ex: trackpad = 3 and mouse wheel = 120
- if (nullLowestDeltaTimeout) { clearTimeout(nullLowestDeltaTimeout); }
- nullLowestDeltaTimeout = setTimeout(nullLowestDelta, 200);
- return ($.event.dispatch || $.event.handle).apply(this, args);
- }
- function nullLowestDelta() {
- lowestDelta = null;
- }
- function shouldAdjustOldDeltas(orgEvent, absDelta) {
- // If this is an older event and the delta is divisable by 120,
- // then we are assuming that the browser is treating this as an
- // older mouse wheel event and that we should divide the deltas
- // by 40 to try and get a more usable deltaFactor.
- // Side note, this actually impacts the reported scroll distance
- // in older browsers and can cause scrolling to be slower than native.
- // Turn this off by setting $.event.special.mousewheel.settings.adjustOldDeltas to false.
- return special.settings.adjustOldDeltas && orgEvent.type === 'mousewheel' && absDelta % 120 === 0;
- }
- }));
- /* Copyright (c) 2012, 2014 Hyeonje Alex Jun and other contributors
- * Licensed under the MIT License
- */
- (function (factory) {
- 'use strict';
- if (typeof define === 'function' && define.amd) {
- // AMD. Register as an anonymous module.
- define(['jquery'], factory);
- } else if (typeof exports === 'object') {
- // Node/CommonJS
- factory(require('jquery'));
- } else {
- // Browser globals
- factory(jQuery);
- }
- }(function ($) {
- 'use strict';
- // The default settings for the plugin
- var defaultSettings = {
- wheelSpeed: 10,
- wheelPropagation: false,
- minScrollbarLength: null,
- useBothWheelAxes: false,
- useKeyboard: true,
- suppressScrollX: false,
- suppressScrollY: false,
- scrollXMarginOffset: 0,
- scrollYMarginOffset: 0,
- includePadding: false
- };
- var getEventClassName = (function () {
- var incrementingId = 0;
- return function () {
- var id = incrementingId;
- incrementingId += 1;
- return '.perfect-scrollbar-' + id;
- };
- }());
- $.fn.perfectScrollbar = function (suppliedSettings, option) {
- return this.each(function () {
- // Use the default settings
- var settings = $.extend(true, {}, defaultSettings),
- $this = $(this);
- if (typeof suppliedSettings === "object") {
- // But over-ride any supplied
- $.extend(true, settings, suppliedSettings);
- } else {
- // If no settings were supplied, then the first param must be the option
- option = suppliedSettings;
- }
- // Catch options
- if (option === 'update') {
- if ($this.data('perfect-scrollbar-update')) {
- $this.data('perfect-scrollbar-update')();
- }
- return $this;
- }
- else if (option === 'destroy') {
- if ($this.data('perfect-scrollbar-destroy')) {
- $this.data('perfect-scrollbar-destroy')();
- }
- return $this;
- }
- if ($this.data('perfect-scrollbar')) {
- // if there's already perfect-scrollbar
- return $this.data('perfect-scrollbar');
- }
- // Or generate new perfectScrollbar
- // Set class to the container
- $this.addClass('ps-container');
- var $scrollbarXRail = $("<div class='ps-scrollbar-x-rail'></div>").appendTo($this),
- $scrollbarYRail = $("<div class='ps-scrollbar-y-rail'></div>").appendTo($this),
- $scrollbarX = $("<div class='ps-scrollbar-x'></div>").appendTo($scrollbarXRail),
- $scrollbarY = $("<div class='ps-scrollbar-y'></div>").appendTo($scrollbarYRail),
- scrollbarXActive,
- scrollbarYActive,
- containerWidth,
- containerHeight,
- contentWidth,
- contentHeight,
- scrollbarXWidth,
- scrollbarXLeft,
- scrollbarXBottom = parseInt($scrollbarXRail.css('bottom'), 10),
- isScrollbarXUsingBottom = scrollbarXBottom === scrollbarXBottom, // !isNaN
- scrollbarXTop = isScrollbarXUsingBottom ? null : parseInt($scrollbarXRail.css('top'), 10),
- scrollbarYHeight,
- scrollbarYTop,
- scrollbarYRight = parseInt($scrollbarYRail.css('right'), 10),
- isScrollbarYUsingRight = scrollbarYRight === scrollbarYRight, // !isNaN
- scrollbarYLeft = isScrollbarYUsingRight ? null: parseInt($scrollbarYRail.css('left'), 10),
- isRtl = $this.css('direction') === "rtl",
- eventClassName = getEventClassName();
- var updateContentScrollTop = function (currentTop, deltaY) {
- var newTop = currentTop + deltaY,
- maxTop = containerHeight - scrollbarYHeight;
- if (newTop < 0) {
- scrollbarYTop = 0;
- }
- else if (newTop > maxTop) {
- scrollbarYTop = maxTop;
- }
- else {
- scrollbarYTop = newTop;
- }
- var scrollTop = parseInt(scrollbarYTop * (contentHeight - containerHeight) / (containerHeight - scrollbarYHeight), 10);
- $this.scrollTop(scrollTop);
- if (isScrollbarXUsingBottom) {
- $scrollbarXRail.css({bottom: scrollbarXBottom - scrollTop});
- } else {
- $scrollbarXRail.css({top: scrollbarXTop + scrollTop});
- }
- };
- var updateContentScrollLeft = function (currentLeft, deltaX) {
- var newLeft = currentLeft + deltaX,
- maxLeft = containerWidth - scrollbarXWidth;
- if (newLeft < 0) {
- scrollbarXLeft = 0;
- }
- else if (newLeft > maxLeft) {
- scrollbarXLeft = maxLeft;
- }
- else {
- scrollbarXLeft = newLeft;
- }
- var scrollLeft = parseInt(scrollbarXLeft * (contentWidth - containerWidth) / (containerWidth - scrollbarXWidth), 10);
- $this.scrollLeft(scrollLeft);
- if (isScrollbarYUsingRight) {
- $scrollbarYRail.css({right: scrollbarYRight - scrollLeft});
- } else {
- $scrollbarYRail.css({left: scrollbarYLeft + scrollLeft});
- }
- };
- var getSettingsAdjustedThumbSize = function (thumbSize) {
- if (settings.minScrollbarLength) {
- thumbSize = Math.max(thumbSize, settings.minScrollbarLength);
- }
- return thumbSize;
- };
- var updateScrollbarCss = function () {
- var scrollbarXStyles = {width: containerWidth, display: scrollbarXActive ? "inherit": "none"};
- if (isRtl) {
- scrollbarXStyles.left = $this.scrollLeft() + containerWidth - contentWidth;
- } else {
- scrollbarXStyles.left = $this.scrollLeft();
- }
- if (isScrollbarXUsingBottom) {
- scrollbarXStyles.bottom = scrollbarXBottom - $this.scrollTop();
- } else {
- scrollbarXStyles.top = scrollbarXTop + $this.scrollTop();
- }
- $scrollbarXRail.css(scrollbarXStyles);
- var scrollbarYStyles = {top: $this.scrollTop(), height: containerHeight, display: scrollbarYActive ? "inherit": "none"};
- if (isScrollbarYUsingRight) {
- if (isRtl) {
- scrollbarYStyles.right = contentWidth - $this.scrollLeft() - scrollbarYRight - $scrollbarY.outerWidth();
- } else {
- scrollbarYStyles.right = scrollbarYRight - $this.scrollLeft();
- }
- } else {
- if (isRtl) {
- scrollbarYStyles.left = $this.scrollLeft() + containerWidth * 2 - contentWidth - scrollbarYLeft - $scrollbarY.outerWidth();
- } else {
- scrollbarYStyles.left = scrollbarYLeft + $this.scrollLeft();
- }
- }
- $scrollbarYRail.css(scrollbarYStyles);
- $scrollbarX.css({left: scrollbarXLeft, width: scrollbarXWidth});
- $scrollbarY.css({top: scrollbarYTop, height: scrollbarYHeight});
- };
- var updateBarSizeAndPosition = function () {
- containerWidth = settings.includePadding ? $this.innerWidth() : $this.width();
- containerHeight = settings.includePadding ? $this.innerHeight() : $this.height();
- contentWidth = $this.prop('scrollWidth');
- contentHeight = $this.prop('scrollHeight');
- if (!settings.suppressScrollX && containerWidth + settings.scrollXMarginOffset < contentWidth) {
- scrollbarXActive = true;
- scrollbarXWidth = getSettingsAdjustedThumbSize(parseInt(containerWidth * containerWidth / contentWidth, 10));
- scrollbarXLeft = parseInt($this.scrollLeft() * (containerWidth - scrollbarXWidth) / (contentWidth - containerWidth), 10);
- }
- else {
- scrollbarXActive = false;
- scrollbarXWidth = 0;
- scrollbarXLeft = 0;
- $this.scrollLeft(0);
- }
- if (!settings.suppressScrollY && containerHeight + settings.scrollYMarginOffset < contentHeight) {
- scrollbarYActive = true;
- scrollbarYHeight = getSettingsAdjustedThumbSize(parseInt(containerHeight * containerHeight / contentHeight, 10));
- scrollbarYTop = parseInt($this.scrollTop() * (containerHeight - scrollbarYHeight) / (contentHeight - containerHeight), 10);
- }
- else {
- scrollbarYActive = false;
- scrollbarYHeight = 0;
- scrollbarYTop = 0;
- $this.scrollTop(0);
- }
- if (scrollbarYTop >= containerHeight - scrollbarYHeight) {
- scrollbarYTop = containerHeight - scrollbarYHeight;
- }
- if (scrollbarXLeft >= containerWidth - scrollbarXWidth) {
- scrollbarXLeft = containerWidth - scrollbarXWidth;
- }
- updateScrollbarCss();
- };
- var bindMouseScrollXHandler = function () {
- var currentLeft,
- currentPageX;
- $scrollbarX.bind('mousedown' + eventClassName, function (e) {
- currentPageX = e.pageX;
- currentLeft = $scrollbarX.position().left;
- $scrollbarXRail.addClass('in-scrolling');
- e.stopPropagation();
- e.preventDefault();
- });
- $(document).bind('mousemove' + eventClassName, function (e) {
- if ($scrollbarXRail.hasClass('in-scrolling')) {
- updateContentScrollLeft(currentLeft, e.pageX - currentPageX);
- e.stopPropagation();
- e.preventDefault();
- }
- });
- $(document).bind('mouseup' + eventClassName, function (e) {
- if ($scrollbarXRail.hasClass('in-scrolling')) {
- $scrollbarXRail.removeClass('in-scrolling');
- }
- });
- currentLeft =
- currentPageX = null;
- };
- var bindMouseScrollYHandler = function () {
- var currentTop,
- currentPageY;
- $scrollbarY.bind('mousedown' + eventClassName, function (e) {
- currentPageY = e.pageY;
- currentTop = $scrollbarY.position().top;
- $scrollbarYRail.addClass('in-scrolling');
- e.stopPropagation();
- e.preventDefault();
- });
- $(document).bind('mousemove' + eventClassName, function (e) {
- if ($scrollbarYRail.hasClass('in-scrolling')) {
- updateContentScrollTop(currentTop, e.pageY - currentPageY);
- e.stopPropagation();
- e.preventDefault();
- }
- });
- $(document).bind('mouseup' + eventClassName, function (e) {
- if ($scrollbarYRail.hasClass('in-scrolling')) {
- $scrollbarYRail.removeClass('in-scrolling');
- }
- });
- currentTop =
- currentPageY = null;
- };
- // check if the default scrolling should be prevented.
- var shouldPreventDefault = function (deltaX, deltaY) {
- var scrollTop = $this.scrollTop();
- if (deltaX === 0) {
- if (!scrollbarYActive) {
- return false;
- }
- if ((scrollTop === 0 && deltaY > 0) || (scrollTop >= contentHeight - containerHeight && deltaY < 0)) {
- return !settings.wheelPropagation;
- }
- }
- var scrollLeft = $this.scrollLeft();
- if (deltaY === 0) {
- if (!scrollbarXActive) {
- return false;
- }
- if ((scrollLeft === 0 && deltaX < 0) || (scrollLeft >= contentWidth - containerWidth && deltaX > 0)) {
- return !settings.wheelPropagation;
- }
- }
- return true;
- };
- // bind handlers
- var bindMouseWheelHandler = function () {
- // FIXME: Backward compatibility.
- // After e.deltaFactor applied, wheelSpeed should have smaller value.
- // Currently, there's no way to change the settings after the scrollbar initialized.
- // But if the way is implemented in the future, wheelSpeed should be reset.
- settings.wheelSpeed /= 10;
- var shouldPrevent = false;
- $this.bind('mousewheel' + eventClassName, function (e, deprecatedDelta, deprecatedDeltaX, deprecatedDeltaY) {
- var deltaX = e.deltaX * e.deltaFactor || deprecatedDeltaX,
- deltaY = e.deltaY * e.deltaFactor || deprecatedDeltaY;
- shouldPrevent = false;
- if (!settings.useBothWheelAxes) {
- // deltaX will only be used for horizontal scrolling and deltaY will
- // only be used for vertical scrolling - this is the default
- $this.scrollTop($this.scrollTop() - (deltaY * settings.wheelSpeed));
- $this.scrollLeft($this.scrollLeft() + (deltaX * settings.wheelSpeed));
- } else if (scrollbarYActive && !scrollbarXActive) {
- // only vertical scrollbar is active and useBothWheelAxes option is
- // active, so let's scroll vertical bar using both mouse wheel axes
- if (deltaY) {
- $this.scrollTop($this.scrollTop() - (deltaY * settings.wheelSpeed));
- } else {
- $this.scrollTop($this.scrollTop() + (deltaX * settings.wheelSpeed));
- }
- shouldPrevent = true;
- } else if (scrollbarXActive && !scrollbarYActive) {
- // useBothWheelAxes and only horizontal bar is active, so use both
- // wheel axes for horizontal bar
- if (deltaX) {
- $this.scrollLeft($this.scrollLeft() + (deltaX * settings.wheelSpeed));
- } else {
- $this.scrollLeft($this.scrollLeft() - (deltaY * settings.wheelSpeed));
- }
- shouldPrevent = true;
- }
- // update bar position
- updateBarSizeAndPosition();
- shouldPrevent = (shouldPrevent || shouldPreventDefault(deltaX, deltaY));
- if (shouldPrevent) {
- e.stopPropagation();
- e.preventDefault();
- }
- });
- // fix Firefox scroll problem
- $this.bind('MozMousePixelScroll' + eventClassName, function (e) {
- if (shouldPrevent) {
- e.preventDefault();
- }
- });
- };
- var bindKeyboardHandler = function () {
- var hovered = false;
- $this.bind('mouseenter' + eventClassName, function (e) {
- hovered = true;
- });
- $this.bind('mouseleave' + eventClassName, function (e) {
- hovered = false;
- });
- var shouldPrevent = false;
- $(document).bind('keydown' + eventClassName, function (e) {
- if (!hovered || $(document.activeElement).is(":input,[contenteditable]")) {
- return;
- }
- var deltaX = 0,
- deltaY = 0;
- switch (e.which) {
- case 37: // left
- deltaX = -30;
- break;
- case 38: // up
- deltaY = 30;
- break;
- case 39: // right
- deltaX = 30;
- break;
- case 40: // down
- deltaY = -30;
- break;
- case 33: // page up
- deltaY = 90;
- break;
- case 32: // space bar
- case 34: // page down
- deltaY = -90;
- break;
- case 35: // end
- deltaY = -containerHeight;
- break;
- case 36: // home
- deltaY = containerHeight;
- break;
- default:
- return;
- }
- $this.scrollTop($this.scrollTop() - deltaY);
- $this.scrollLeft($this.scrollLeft() + deltaX);
- shouldPrevent = shouldPreventDefault(deltaX, deltaY);
- if (shouldPrevent) {
- e.preventDefault();
- }
- });
- };
- var bindRailClickHandler = function () {
- var stopPropagation = function (e) { e.stopPropagation(); };
- $scrollbarY.bind('click' + eventClassName, stopPropagation);
- $scrollbarYRail.bind('click' + eventClassName, function (e) {
- var halfOfScrollbarLength = parseInt(scrollbarYHeight / 2, 10),
- positionTop = e.pageY - $scrollbarYRail.offset().top - halfOfScrollbarLength,
- maxPositionTop = containerHeight - scrollbarYHeight,
- positionRatio = positionTop / maxPositionTop;
- if (positionRatio < 0) {
- positionRatio = 0;
- } else if (positionRatio > 1) {
- positionRatio = 1;
- }
- $this.scrollTop((contentHeight - containerHeight) * positionRatio);
- });
- $scrollbarX.bind('click' + eventClassName, stopPropagation);
- $scrollbarXRail.bind('click' + eventClassName, function (e) {
- var halfOfScrollbarLength = parseInt(scrollbarXWidth / 2, 10),
- positionLeft = e.pageX - $scrollbarXRail.offset().left - halfOfScrollbarLength,
- maxPositionLeft = containerWidth - scrollbarXWidth,
- positionRatio = positionLeft / maxPositionLeft;
- if (positionRatio < 0) {
- positionRatio = 0;
- } else if (positionRatio > 1) {
- positionRatio = 1;
- }
- $this.scrollLeft((contentWidth - containerWidth) * positionRatio);
- });
- };
- // bind mobile touch handler
- var bindMobileTouchHandler = function () {
- var applyTouchMove = function (differenceX, differenceY) {
- $this.scrollTop($this.scrollTop() - differenceY);
- $this.scrollLeft($this.scrollLeft() - differenceX);
- // update bar position
- updateBarSizeAndPosition();
- };
- var startCoords = {},
- startTime = 0,
- speed = {},
- breakingProcess = null,
- inGlobalTouch = false;
- $(window).bind("touchstart" + eventClassName, function (e) {
- inGlobalTouch = true;
- });
- $(window).bind("touchend" + eventClassName, function (e) {
- inGlobalTouch = false;
- });
- $this.bind("touchstart" + eventClassName, function (e) {
- var touch = e.originalEvent.targetTouches[0];
- startCoords.pageX = touch.pageX;
- startCoords.pageY = touch.pageY;
- startTime = (new Date()).getTime();
- if (breakingProcess !== null) {
- clearInterval(breakingProcess);
- }
- e.stopPropagation();
- });
- $this.bind("touchmove" + eventClassName, function (e) {
- if (!inGlobalTouch && e.originalEvent.targetTouches.length === 1) {
- var touch = e.originalEvent.targetTouches[0];
- var currentCoords = {};
- currentCoords.pageX = touch.pageX;
- currentCoords.pageY = touch.pageY;
- var differenceX = currentCoords.pageX - startCoords.pageX,
- differenceY = currentCoords.pageY - startCoords.pageY;
- applyTouchMove(differenceX, differenceY);
- startCoords = currentCoords;
- var currentTime = (new Date()).getTime();
- var timeGap = currentTime - startTime;
- if (timeGap > 0) {
- speed.x = differenceX / timeGap;
- speed.y = differenceY / timeGap;
- startTime = currentTime;
- }
- e.preventDefault();
- }
- });
- $this.bind("touchend" + eventClassName, function (e) {
- clearInterval(breakingProcess);
- breakingProcess = setInterval(function () {
- if (Math.abs(speed.x) < 0.01 && Math.abs(speed.y) < 0.01) {
- clearInterval(breakingProcess);
- return;
- }
- applyTouchMove(speed.x * 30, speed.y * 30);
- speed.x *= 0.8;
- speed.y *= 0.8;
- }, 10);
- });
- };
- var bindScrollHandler = function () {
- $this.bind('scroll' + eventClassName, function (e) {
- updateBarSizeAndPosition();
- });
- };
- var destroy = function () {
- $this.unbind(eventClassName);
- $(window).unbind(eventClassName);
- $(document).unbind(eventClassName);
- $this.data('perfect-scrollbar', null);
- $this.data('perfect-scrollbar-update', null);
- $this.data('perfect-scrollbar-destroy', null);
- $scrollbarX.remove();
- $scrollbarY.remove();
- $scrollbarXRail.remove();
- $scrollbarYRail.remove();
- // clean all variables
- $scrollbarXRail =
- $scrollbarYRail =
- $scrollbarX =
- $scrollbarY =
- scrollbarXActive =
- scrollbarYActive =
- containerWidth =
- containerHeight =
- contentWidth =
- contentHeight =
- scrollbarXWidth =
- scrollbarXLeft =
- scrollbarXBottom =
- isScrollbarXUsingBottom =
- scrollbarXTop =
- scrollbarYHeight =
- scrollbarYTop =
- scrollbarYRight =
- isScrollbarYUsingRight =
- scrollbarYLeft =
- isRtl =
- eventClassName = null;
- };
- var ieSupport = function (version) {
- $this.addClass('ie').addClass('ie' + version);
- var bindHoverHandlers = function () {
- var mouseenter = function () {
- $(this).addClass('hover');
- };
- var mouseleave = function () {
- $(this).removeClass('hover');
- };
- $this.bind('mouseenter' + eventClassName, mouseenter).bind('mouseleave' + eventClassName, mouseleave);
- $scrollbarXRail.bind('mouseenter' + eventClassName, mouseenter).bind('mouseleave' + eventClassName, mouseleave);
- $scrollbarYRail.bind('mouseenter' + eventClassName, mouseenter).bind('mouseleave' + eventClassName, mouseleave);
- $scrollbarX.bind('mouseenter' + eventClassName, mouseenter).bind('mouseleave' + eventClassName, mouseleave);
- $scrollbarY.bind('mouseenter' + eventClassName, mouseenter).bind('mouseleave' + eventClassName, mouseleave);
- };
- var fixIe6ScrollbarPosition = function () {
- updateScrollbarCss = function () {
- var scrollbarXStyles = {left: scrollbarXLeft + $this.scrollLeft(), width: scrollbarXWidth};
- if (isScrollbarXUsingBottom) {
- scrollbarXStyles.bottom = scrollbarXBottom;
- } else {
- scrollbarXStyles.top = scrollbarXTop;
- }
- $scrollbarX.css(scrollbarXStyles);
- var scrollbarYStyles = {top: scrollbarYTop + $this.scrollTop(), height: scrollbarYHeight};
- if (isScrollbarYUsingRight) {
- scrollbarYStyles.right = scrollbarYRight;
- } else {
- scrollbarYStyles.left = scrollbarYLeft;
- }
- $scrollbarY.css(scrollbarYStyles);
- $scrollbarX.hide().show();
- $scrollbarY.hide().show();
- };
- };
- if (version === 6) {
- bindHoverHandlers();
- fixIe6ScrollbarPosition();
- }
- };
- var supportsTouch = (('ontouchstart' in window) || window.DocumentTouch && document instanceof window.DocumentTouch);
- var initialize = function () {
- var ieMatch = navigator.userAgent.toLowerCase().match(/(msie) ([\w.]+)/);
- if (ieMatch && ieMatch[1] === 'msie') {
- // must be executed at first, because 'ieSupport' may addClass to the container
- ieSupport(parseInt(ieMatch[2], 10));
- }
- updateBarSizeAndPosition();
- bindScrollHandler();
- bindMouseScrollXHandler();
- bindMouseScrollYHandler();
- bindRailClickHandler();
- if (supportsTouch) {
- bindMobileTouchHandler();
- }
- if ($this.mousewheel) {
- bindMouseWheelHandler();
- }
- if (settings.useKeyboard) {
- bindKeyboardHandler();
- }
- $this.data('perfect-scrollbar', $this);
- $this.data('perfect-scrollbar-update', updateBarSizeAndPosition);
- $this.data('perfect-scrollbar-destroy', destroy);
- };
- // initialize
- initialize();
- return $this;
- });
- };
- }));
|