| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614 |
- /*!
- * jScrollPane - v2.2.1 - 2018-09-27
- * http://jscrollpane.kelvinluck.com/
- *
- * Copyright (c) 2014 Kelvin Luck
- * Copyright (c) 2017-2018 Tuukka Pasanen
- * Dual licensed under the MIT or GPL licenses.
- */
- // Script: jScrollPane - cross browser customisable scrollbars
- //
- // *Version: 2.2.1, Last updated: 2018-09-27*
- //
- // Project Home - http://jscrollpane.kelvinluck.com/
- // GitHub - http://github.com/vitch/jScrollPane
- // CND - https://cdnjs.com/libraries/jScrollPane
- // Source - https://cdnjs.cloudflare.com/ajax/libs/jScrollPane/2.2.1/script/jquery.jscrollpane.min.js
- // (Minified) - https://cdnjs.cloudflare.com/ajax/libs/jScrollPane/2.2.1/script/jquery.jscrollpane.js
- // CSS - https://cdnjs.cloudflare.com/ajax/libs/jScrollPane/2.2.1/style/jquery.jscrollpane.css
- // (Minified) - https://cdnjs.cloudflare.com/ajax/libs/jScrollPane/2.2.1/style/jquery.jscrollpane.min.css
- //
- // About: License
- //
- // Copyright (c) 2017 Kelvin Luck
- // Copyright (c) 2017-2018 Tuukka Pasanen
- // Dual licensed under the MIT or GPL Version 2 licenses.
- // http://jscrollpane.kelvinluck.com/MIT-LICENSE.txt
- // http://jscrollpane.kelvinluck.com/GPL-LICENSE.txt
- //
- // About: Examples
- //
- // All examples and demos are available through the jScrollPane example site at:
- // http://jscrollpane.kelvinluck.com/
- //
- // About: Support and Testing
- //
- // This plugin is tested on the browsers below and has been found to work reliably on them. If you run
- // into a problem on one of the supported browsers then please visit the support section on the jScrollPane
- // website (http://jscrollpane.kelvinluck.com/) for more information on getting support. You are also
- // welcome to fork the project on GitHub if you can contribute a fix for a given issue.
- //
- // jQuery Versions - jQuery 3.x. Although script should work from jQuery 1.1 and up but no promises are made.
- // Browsers Tested - See jQuery browser support page: https://jquery.com/browser-support/. Only modern
- // browsers are supported.
- //
- // About: Release History
- //
- // 2.2.1 - (2018-09-27) No changed applied to release so same as RC1/2
- // 2.2.1-rc.2 - (2018-06-14) Sucked NPM release have to make new Release.. this is 2018!
- // 2.2.1-rc.1 - (2018-06-14) Fixed CSSLint warnings which can lead CSS problems in
- // production! Please report a issue if this breaks something!
- // * Merged:
- // - #360 Register to globally available version of jQuery
- // 2.2.0 - (2018-05-16) No changes to RC1
- // 2.2.0-rc.1 - (2018-04-28) Merged resize sensor to find out size changes of screen and
- // again little bit tuned this to support more npm goodies.
- // * Merged:
- // - #361 Event based reinitialising - Resize Sensor
- // - #359 Use npm scripts and local dev dependencies to build the project
- // 2.1.3 - (2018-04-04) No changes from Release Candidate 2 so making release
- // 2.1.3-rc.2 - (2018-03-13) Now using 'script/jquery.jscrollpane.min.js' main
- // in package.json rather than 'Gruntfile.js'
- // 2.1.3-rc.1 - (2018-03-05) Moving Gruntfile.js to root and example HTML
- // to subdirectory examples
- // 2.1.2 - (2018-02-16) Just on console.log remove and Release!
- // This version should play nicely with NPM
- // 2.1.2-rc.2 - (2018-02-03) Update package.json main-tag
- // 2.1.2-rc.1 - (2018-01-18) Release on NPM.
- // 2.1.1 - (2018-01-12) As everyone stays silent then we just release! No changes from RC.1
- // 2.1.1-rc.1 - (2017-12-23) Started to slowly merge stuff (HO HO HO Merry Christmas!)
- // * Merged
- // - #349 - ScrollPane reinitialization should adapt to changed container size
- // - #335 Set drag bar width/height with .css instead of .width/.height
- // - #297 added two settings: always show HScroll and VScroll
- // * Bugs
- // - #8 Make it possible to tell a scrollbar to be "always on"
- // 2.1.0 - (2017-12-16) Update jQuery to version 3.x
- (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(jQuery || require('jquery'));
- } else {
- // Browser globals
- factory(jQuery);
- }
- }(function ($) {
- $.fn.jScrollPane = function (settings) {
- // JScrollPane "class" - public methods are available through $('selector').data('jsp')
- function JScrollPane(elem, s) {
- var settings, jsp = this, pane, paneWidth, paneHeight, container, contentWidth, contentHeight,
- percentInViewH, percentInViewV, isScrollableV, isScrollableH, verticalDrag, dragMaxY,
- verticalDragPosition, horizontalDrag, dragMaxX, horizontalDragPosition,
- verticalBar, verticalTrack, scrollbarWidth, verticalTrackHeight, verticalDragHeight, arrowUp, arrowDown,
- horizontalBar, horizontalTrack, horizontalTrackWidth, horizontalDragWidth, arrowLeft, arrowRight,
- reinitialiseInterval, originalPadding, originalPaddingTotalWidth, previousContentWidth,
- wasAtTop = true, wasAtLeft = true, wasAtBottom = false, wasAtRight = false,
- originalElement = elem.clone(false, false).empty(), resizeEventsAdded = false,
- mwEvent = $.fn.mwheelIntent ? 'mwheelIntent' : 'mousewheel';
- var reinitialiseFn = function () {
- // if size has changed then reinitialise
- if (settings.resizeSensorDelay > 0) {
- setTimeout(function () {
- initialise(settings);
- }, settings.resizeSensorDelay);
- } else {
- initialise(settings);
- }
- };
- if (elem.css('box-sizing') === 'border-box') {
- originalPadding = 0;
- originalPaddingTotalWidth = 0;
- } else {
- originalPadding = elem.css('paddingTop') + ' ' +
- elem.css('paddingRight') + ' ' +
- elem.css('paddingBottom') + ' ' +
- elem.css('paddingLeft');
- originalPaddingTotalWidth = (parseInt(elem.css('paddingLeft'), 10) || 0) +
- (parseInt(elem.css('paddingRight'), 10) || 0);
- }
- function initialise(s) {
- var /*firstChild, lastChild, */isMaintainingPositon, lastContentX, lastContentY,
- hasContainingSpaceChanged, originalScrollTop, originalScrollLeft,
- newPaneWidth, newPaneHeight, maintainAtBottom = false, maintainAtRight = false;
- settings = s;
- if (pane === undefined) {
- originalScrollTop = elem.scrollTop();
- originalScrollLeft = elem.scrollLeft();
- elem.css(
- {
- overflow: 'hidden',
- padding: 0
- }
- );
- // TODO: Deal with where width/ height is 0 as it probably means the element is hidden and we should
- // come back to it later and check once it is unhidden...
- paneWidth = elem.outerWidth() + originalPaddingTotalWidth;
- paneHeight = elem.outerHeight();
- elem.width(paneWidth);
- pane = $('<div class="jspPane" />').css('padding', originalPadding).append(elem.children());
- container = $('<div class="jspContainer" />')
- .css({
- 'width': paneWidth + 'px',
- 'height': paneHeight + 'px'
- }
- ).append(pane).appendTo(elem);
- /*
- // Move any margins from the first and last children up to the container so they can still
- // collapse with neighbouring elements as they would before jScrollPane
- firstChild = pane.find(':first-child');
- lastChild = pane.find(':last-child');
- elem.css(
- {
- 'margin-top': firstChild.css('margin-top'),
- 'margin-bottom': lastChild.css('margin-bottom')
- }
- );
- firstChild.css('margin-top', 0);
- lastChild.css('margin-bottom', 0);
- */
- } else {
- elem.css('width', '');
- // To measure the required dimensions accurately, temporarily override the CSS positioning
- // of the container and pane.
- container.css({width: 'auto', height: 'auto'});
- pane.css('position', 'static');
- newPaneWidth = elem.outerWidth() + originalPaddingTotalWidth;
- newPaneHeight = elem.outerHeight();
- pane.css('position', 'absolute');
- maintainAtBottom = settings.stickToBottom && isCloseToBottom();
- maintainAtRight = settings.stickToRight && isCloseToRight();
- hasContainingSpaceChanged = newPaneWidth !== paneWidth || newPaneHeight !== paneHeight;
- paneWidth = newPaneWidth;
- paneHeight = newPaneHeight;
- container.css({width: paneWidth, height: paneHeight});
- // If nothing changed since last check...
- if (!hasContainingSpaceChanged && previousContentWidth == contentWidth && pane.outerHeight() == contentHeight) {
- elem.width(paneWidth);
- return;
- }
- previousContentWidth = contentWidth;
- pane.css('width', '');
- elem.width(paneWidth);
- container.find('>.jspVerticalBar,>.jspHorizontalBar').remove().end();
- }
- pane.css('overflow', 'auto');
- if (s.contentWidth) {
- contentWidth = s.contentWidth;
- } else {
- contentWidth = pane[0].scrollWidth;
- }
- contentHeight = pane[0].scrollHeight;
- pane.css('overflow', '');
- /* Round up in case of rendering errors in Firefox */
- percentInViewH = Math.ceil(paneWidth) / Math.ceil(contentWidth);
- percentInViewV = Math.ceil(paneHeight) / Math.ceil(contentHeight);
- isScrollableV = percentInViewV >= 1 || settings.alwaysShowVScroll;
- isScrollableH = percentInViewH >= 1 || settings.alwaysShowHScroll;
- if (!(isScrollableH || isScrollableV)) {
- elem.removeClass('jspScrollable');
- pane.css({
- top: 0,
- left: 0,
- width: container.width() - originalPaddingTotalWidth
- });
- removeMousewheel();
- removeFocusHandler();
- removeKeyboardNav();
- removeClickOnTrack();
- } else {
- elem.addClass('jspScrollable');
- isMaintainingPositon = settings.maintainPosition && (verticalDragPosition || horizontalDragPosition);
- if (isMaintainingPositon) {
- lastContentX = contentPositionX();
- lastContentY = contentPositionY();
- }
- initialiseVerticalScroll();
- initialiseHorizontalScroll();
- resizeScrollbars();
- if (isMaintainingPositon) {
- scrollToX(maintainAtRight ? (contentWidth - paneWidth) : lastContentX, false);
- scrollToY(maintainAtBottom ? (contentHeight - paneHeight) : lastContentY, false);
- }
- initFocusHandler();
- initMousewheel();
- initTouch();
- if (settings.enableKeyboardNavigation) {
- initKeyboardNav();
- }
- if (settings.clickOnTrack) {
- initClickOnTrack();
- }
- observeHash();
- if (settings.hijackInternalLinks) {
- hijackInternalLinks();
- }
- }
- /* Remove navigation if we don't need to scroll */
- if (percentInViewV >= 1 ) {
- removeMousewheel();
- removeFocusHandler();
- removeKeyboardNav();
- removeVerticalClickOnTrack();
- }
- if (percentInViewH >= 1 ) {
- removeHorizontalClickOnTrack();
- }
- if (!settings.resizeSensor && settings.autoReinitialise && !reinitialiseInterval) {
- reinitialiseInterval = setInterval(
- function () {
- initialise(settings);
- },
- settings.autoReinitialiseDelay
- );
- } else if (!settings.resizeSensor && !settings.autoReinitialise && reinitialiseInterval) {
- clearInterval(reinitialiseInterval);
- }
- if (settings.resizeSensor && !resizeEventsAdded) {
- // detect size change in content
- detectSizeChanges(pane, reinitialiseFn);
- // detect size changes of scroll element
- detectSizeChanges(elem, reinitialiseFn);
- // detect size changes of container
- detectSizeChanges(elem.parent(), reinitialiseFn);
- // add a reinit on window resize also for safety
- window.addEventListener('resize', reinitialiseFn);
- resizeEventsAdded = true;
- }
- if (originalScrollTop && elem.scrollTop(0)) {
- scrollToY(originalScrollTop, false);
- }
- if (originalScrollLeft && elem.scrollLeft(0)) {
- scrollToX(originalScrollLeft, false);
- }
- elem.trigger('jsp-initialised', [isScrollableH || isScrollableV]);
- }
- function detectSizeChanges(element, callback) {
- // create resize event elements - based on resize sensor: https://github.com/flowkey/resize-sensor/
- var resizeWidth, resizeHeight;
- var resizeElement = document.createElement('div');
- var resizeGrowElement = document.createElement('div');
- var resizeGrowChildElement = document.createElement('div');
- var resizeShrinkElement = document.createElement('div');
- var resizeShrinkChildElement = document.createElement('div');
- // add necessary styling
- resizeElement.style.cssText = 'position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: scroll; z-index: -1; visibility: hidden;';
- resizeGrowElement.style.cssText = 'position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: scroll; z-index: -1; visibility: hidden;';
- resizeShrinkElement.style.cssText = 'position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: scroll; z-index: -1; visibility: hidden;';
- resizeGrowChildElement.style.cssText = 'position: absolute; left: 0; top: 0;';
- resizeShrinkChildElement.style.cssText = 'position: absolute; left: 0; top: 0; width: 200%; height: 200%;';
- // Create a function to programmatically update sizes
- var updateSizes = function () {
- resizeGrowChildElement.style.width = resizeGrowElement.offsetWidth + 10 + 'px';
- resizeGrowChildElement.style.height = resizeGrowElement.offsetHeight + 10 + 'px';
- resizeGrowElement.scrollLeft = resizeGrowElement.scrollWidth;
- resizeGrowElement.scrollTop = resizeGrowElement.scrollHeight;
- resizeShrinkElement.scrollLeft = resizeShrinkElement.scrollWidth;
- resizeShrinkElement.scrollTop = resizeShrinkElement.scrollHeight;
- resizeWidth = element.width();
- resizeHeight = element.height();
- };
- // create functions to call when content grows
- var onGrow = function () {
- // check to see if the content has change size
- if (element.width() > resizeWidth || element.height() > resizeHeight) {
- // if size has changed then reinitialise
- callback.apply(this, []);
- }
- // after reinitialising update sizes
- updateSizes();
- };
- // create functions to call when content shrinks
- var onShrink = function () {
- // check to see if the content has change size
- if (element.width() < resizeWidth || element.height() < resizeHeight) {
- // if size has changed then reinitialise
- callback.apply(this, []);
- }
- // after reinitialising update sizes
- updateSizes();
- };
- // bind to scroll events
- resizeGrowElement.addEventListener('scroll', onGrow.bind(this));
- resizeShrinkElement.addEventListener('scroll', onShrink.bind(this));
- // nest elements before adding to pane
- resizeGrowElement.appendChild(resizeGrowChildElement);
- resizeShrinkElement.appendChild(resizeShrinkChildElement);
- resizeElement.appendChild(resizeGrowElement);
- resizeElement.appendChild(resizeShrinkElement);
- element.append(resizeElement);
- // ensure parent element is not statically positioned
- if (window.getComputedStyle(element[0], null).getPropertyValue('position') === 'static') {
- element[0].style.position = 'relative';
- }
- // update sizes initially
- updateSizes();
- }
- function initialiseVerticalScroll() {
- if (isScrollableV) {
- container.append(
- $('<div class="jspVerticalBar" />').append(
- $('<div class="jspCap jspCapTop" />'),
- $('<div class="jspTrack" />').append(
- $('<div class="jspDrag" />').append(
- $('<div class="jspDragTop" />'),
- $('<div class="jspDragBottom" />')
- )
- ),
- $('<div class="jspCap jspCapBottom" />')
- )
- );
- verticalBar = container.find('>.jspVerticalBar');
- verticalTrack = verticalBar.find('>.jspTrack');
- verticalDrag = verticalTrack.find('>.jspDrag');
- if (percentInViewV >= 1) {
- verticalBar.addClass("jspAllInView");
- }
- if (settings.showArrows) {
- arrowUp = $('<a class="jspArrow jspArrowUp" />').on(
- 'mousedown.jsp', getArrowScroll(0, -1)
- ).on('click.jsp', nil);
- arrowDown = $('<a class="jspArrow jspArrowDown" />').on(
- 'mousedown.jsp', getArrowScroll(0, 1)
- ).on('click.jsp', nil);
- if (settings.arrowScrollOnHover) {
- arrowUp.on('mouseover.jsp', getArrowScroll(0, -1, arrowUp));
- arrowDown.on('mouseover.jsp', getArrowScroll(0, 1, arrowDown));
- }
- appendArrows(verticalTrack, settings.verticalArrowPositions, arrowUp, arrowDown);
- }
- verticalTrackHeight = paneHeight;
- container.find('>.jspVerticalBar>.jspCap:visible,>.jspVerticalBar>.jspArrow').each(
- function () {
- verticalTrackHeight -= $(this).outerHeight();
- }
- );
- verticalDrag.on(
- "mouseenter",
- function () {
- verticalDrag.addClass('jspHover');
- }
- ).on(
- "mouseleave",
- function () {
- verticalDrag.removeClass('jspHover');
- }
- ).on(
- 'mousedown.jsp',
- function (e) {
- // Stop IE from allowing text selection
- $('html').on('dragstart.jsp selectstart.jsp', nil);
- verticalDrag.addClass('jspActive');
- var startY = e.pageY - verticalDrag.position().top;
- $('html').on(
- 'mousemove.jsp',
- function (e) {
- positionDragY(e.pageY - startY, false);
- }
- ).on('mouseup.jsp mouseleave.jsp', cancelDrag);
- return false;
- }
- );
- sizeVerticalScrollbar();
- }
- }
- function sizeVerticalScrollbar() {
- verticalTrack.height(verticalTrackHeight + "px");
- verticalDragPosition = 0;
- scrollbarWidth = settings.verticalGutter + verticalTrack.outerWidth();
- // Make the pane thinner to allow for the vertical scrollbar
- pane.width(paneWidth - scrollbarWidth - originalPaddingTotalWidth);
- // Add margin to the left of the pane if scrollbars are on that side (to position
- // the scrollbar on the left or right set it's left or right property in CSS)
- try {
- if (verticalBar.position().left === 0) {
- pane.css('margin-left', scrollbarWidth + 'px');
- }
- } catch (err) {
- }
- }
- function initialiseHorizontalScroll() {
- if (isScrollableH) {
- //container.css("height", contentHeight + verticalTrack.width() + 1 + "px");
- container.append(
- $('<div class="jspHorizontalBar" />').append(
- $('<div class="jspCap jspCapLeft" />'),
- $('<div class="jspTrack" />').append(
- $('<div class="jspDrag" />').append(
- $('<div class="jspDragLeft" />'),
- $('<div class="jspDragRight" />')
- )
- ),
- $('<div class="jspCap jspCapRight" />')
- )
- );
- horizontalBar = container.find('>.jspHorizontalBar');
- horizontalTrack = horizontalBar.find('>.jspTrack');
- horizontalDrag = horizontalTrack.find('>.jspDrag');
- if (percentInViewH >= 1) {
- horizontalBar.addClass("jspAllInView");
- }
- if (settings.showArrows) {
- arrowLeft = $('<a class="jspArrow jspArrowLeft" />').on(
- 'mousedown.jsp', getArrowScroll(-1, 0)
- ).on('click.jsp', nil);
- arrowRight = $('<a class="jspArrow jspArrowRight" />').on(
- 'mousedown.jsp', getArrowScroll(1, 0)
- ).on('click.jsp', nil);
- if (settings.arrowScrollOnHover) {
- arrowLeft.on('mouseover.jsp', getArrowScroll(-1, 0, arrowLeft));
- arrowRight.on('mouseover.jsp', getArrowScroll(1, 0, arrowRight));
- }
- appendArrows(horizontalTrack, settings.horizontalArrowPositions, arrowLeft, arrowRight);
- }
- horizontalDrag.on(
- "mouseenter",
- function () {
- horizontalDrag.addClass('jspHover');
- }
- ).on(
- "mouseleave",
- function () {
- horizontalDrag.removeClass('jspHover');
- }
- ).on(
- 'mousedown.jsp',
- function (e) {
- // Stop IE from allowing text selection
- $('html').on('dragstart.jsp selectstart.jsp', nil);
- horizontalDrag.addClass('jspActive');
- var startX = e.pageX - horizontalDrag.position().left;
- $('html').on(
- 'mousemove.jsp',
- function (e) {
- positionDragX(e.pageX - startX, false);
- }
- ).on('mouseup.jsp mouseleave.jsp', cancelDrag);
- return false;
- }
- );
- horizontalTrackWidth = container.innerWidth();
- sizeHorizontalScrollbar();
- }
- }
- function sizeHorizontalScrollbar() {
- container.find('>.jspHorizontalBar>.jspCap:visible,>.jspHorizontalBar>.jspArrow').each(
- function () {
- horizontalTrackWidth -= $(this).outerWidth();
- }
- );
- horizontalTrack.width(horizontalTrackWidth + 'px');
- horizontalDragPosition = 0;
- }
- function resizeScrollbars() {
- if (isScrollableH && isScrollableV) {
- var horizontalTrackHeight = horizontalTrack.outerHeight(),
- verticalTrackWidth = verticalTrack.outerWidth();
- verticalTrackHeight -= horizontalTrackHeight;
- $(horizontalBar).find('>.jspCap:visible,>.jspArrow').each(
- function () {
- horizontalTrackWidth += $(this).outerWidth();
- }
- );
- horizontalTrackWidth -= verticalTrackWidth;
- paneHeight -= verticalTrackWidth;
- paneWidth -= horizontalTrackHeight;
- horizontalTrack.parent().append(
- $('<div class="jspCorner" />').css('width', horizontalTrackHeight + 'px')
- );
- sizeVerticalScrollbar();
- sizeHorizontalScrollbar();
- }
- // reflow content
- if (isScrollableH) {
- pane.width((container.outerWidth() - originalPaddingTotalWidth) + 'px');
- }
- contentHeight = pane.outerHeight();
- percentInViewV = paneHeight / (contentHeight - horizontalTrackHeight);
- percentInViewH = container.outerWidth() / contentWidth;
- if (isScrollableH) {
- horizontalDragWidth = Math.ceil(percentInViewH * horizontalTrackWidth);
- if (horizontalDragWidth > settings.horizontalDragMaxWidth) {
- horizontalDragWidth = settings.horizontalDragMaxWidth;
- } else if (horizontalDragWidth < settings.horizontalDragMinWidth) {
- horizontalDragWidth = settings.horizontalDragMinWidth;
- }
- horizontalDrag.css('width', horizontalDragWidth + 'px');
- dragMaxX = horizontalTrackWidth - horizontalDragWidth;
- _positionDragX(horizontalDragPosition); // To update the state for the arrow buttons
- }
- if (isScrollableV) {
- verticalDragHeight = Math.ceil(percentInViewV * verticalTrackHeight);
- if (verticalDragHeight > settings.verticalDragMaxHeight) {
- verticalDragHeight = settings.verticalDragMaxHeight;
- } else if (verticalDragHeight < settings.verticalDragMinHeight) {
- verticalDragHeight = settings.verticalDragMinHeight;
- }
- verticalDrag.css('height', verticalDragHeight + 'px');
- dragMaxY = verticalTrackHeight - verticalDragHeight;
- _positionDragY(verticalDragPosition); // To update the state for the arrow buttons
- }
- }
- function appendArrows(ele, p, a1, a2) {
- var p1 = "before", p2 = "after", aTemp;
- // Sniff for mac... Is there a better way to determine whether the arrows would naturally appear
- // at the top or the bottom of the bar?
- if (p == "os") {
- p = /Mac/.test(navigator.platform) ? "after" : "split";
- }
- if (p == p1) {
- p2 = p;
- } else if (p == p2) {
- p1 = p;
- aTemp = a1;
- a1 = a2;
- a2 = aTemp;
- }
- ele[p1](a1)[p2](a2);
- }
- function getArrowScroll(dirX, dirY, ele) {
- return function () {
- arrowScroll(dirX, dirY, this, ele);
- this.blur();
- return false;
- };
- }
- function arrowScroll(dirX, dirY, arrow, ele) {
- if (dirX !== 0 && percentInViewH >= 1) return;
- if (dirY !== 0 && percentInViewV >= 1) return;
- arrow = $(arrow).addClass('jspActive');
- var eve,
- scrollTimeout,
- isFirst = true,
- doScroll = function () {
- if (dirX !== 0) {
- jsp.scrollByX(dirX * settings.arrowButtonSpeed);
- }
- if (dirY !== 0) {
- jsp.scrollByY(dirY * settings.arrowButtonSpeed);
- }
- scrollTimeout = setTimeout(doScroll, isFirst ? settings.initialDelay : settings.arrowRepeatFreq);
- isFirst = false;
- };
- doScroll();
- eve = ele ? 'mouseout.jsp' : 'mouseup.jsp';
- ele = ele || $('html');
- ele.on(
- eve,
- function () {
- arrow.removeClass('jspActive');
- if (scrollTimeout) {
- clearTimeout(scrollTimeout);
- }
- scrollTimeout = null;
- ele.off(eve);
- }
- );
- }
- function initClickOnTrack() {
- removeClickOnTrack();
- if (isScrollableV) {
- verticalTrack.on(
- 'mousedown.jsp',
- function (e) {
- if (e.originalTarget === undefined || e.originalTarget == e.currentTarget) {
- var clickedTrack = $(this),
- offset = clickedTrack.offset(),
- direction = e.pageY - offset.top - verticalDragPosition,
- scrollTimeout,
- isFirst = true,
- doScroll = function () {
- var offset = clickedTrack.offset(),
- pos = e.pageY - offset.top - verticalDragHeight / 2,
- contentDragY = paneHeight * settings.scrollPagePercent,
- dragY = dragMaxY * contentDragY / (contentHeight - paneHeight);
- if (clickedTrack.hasClass("disabled")) return;
- if (direction < 0) {
- if (verticalDragPosition - dragY > pos) {
- jsp.scrollByY(-contentDragY);
- } else {
- positionDragY(pos);
- }
- } else if (direction > 0) {
- if (verticalDragPosition + dragY < pos) {
- jsp.scrollByY(contentDragY);
- } else {
- positionDragY(pos);
- }
- } else {
- cancelClick();
- return;
- }
- scrollTimeout = setTimeout(doScroll, isFirst ? settings.initialDelay : settings.trackClickRepeatFreq);
- isFirst = false;
- },
- cancelClick = function () {
- if (scrollTimeout) {
- clearTimeout(scrollTimeout);
- }
- scrollTimeout = null;
- $(document).off('mouseup.jsp', cancelClick);
- };
- if (!clickedTrack.hasClass("disabled")) {
- doScroll();
- $(document).on('mouseup.jsp', cancelClick);
- return false;
- }
- }
- }
- );
- }
- if (isScrollableH) {
- horizontalTrack.on(
- 'mousedown.jsp',
- function (e) {
- if (e.originalTarget === undefined || e.originalTarget == e.currentTarget) {
- var clickedTrack = $(this),
- offset = clickedTrack.offset(),
- direction = e.pageX - offset.left - horizontalDragPosition,
- scrollTimeout,
- isFirst = true,
- doScroll = function () {
- var offset = clickedTrack.offset(),
- pos = e.pageX - offset.left - horizontalDragWidth / 2,
- contentDragX = paneWidth * settings.scrollPagePercent,
- dragX = dragMaxX * contentDragX / (contentWidth - paneWidth);
- if (direction < 0) {
- if (horizontalDragPosition - dragX > pos) {
- jsp.scrollByX(-contentDragX);
- } else {
- positionDragX(pos);
- }
- } else if (direction > 0) {
- if (horizontalDragPosition + dragX < pos) {
- jsp.scrollByX(contentDragX);
- } else {
- positionDragX(pos);
- }
- } else {
- cancelClick();
- return;
- }
- scrollTimeout = setTimeout(doScroll, isFirst ? settings.initialDelay : settings.trackClickRepeatFreq);
- isFirst = false;
- },
- cancelClick = function () {
- if (scrollTimeout) {
- clearTimeout(scrollTimeout);
- }
- scrollTimeout = null;
- $(document).off('mouseup.jsp', cancelClick);
- };
- if (!clickedTrack.hasClass("disabled")) {
- doScroll();
- $(document).on('mouseup.jsp', cancelClick);
- return false;
- }
- }
- }
- );
- }
- }
- function removeClickOnTrack() {
- removeHorizontalClickOnTrack();
- removeVerticalClickOnTrack();
- }
- function removeHorizontalClickOnTrack() {
- if (horizontalTrack) {
- horizontalTrack.off('mousedown.jsp');
- }
- }
- function removeVerticalClickOnTrack() {
- if (verticalTrack) {
- verticalTrack.off('mousedown.jsp');
- }
- }
- function cancelDrag() {
- $('html').off('dragstart.jsp selectstart.jsp mousemove.jsp mouseup.jsp mouseleave.jsp');
- if (verticalDrag) {
- verticalDrag.removeClass('jspActive');
- }
- if (horizontalDrag) {
- horizontalDrag.removeClass('jspActive');
- }
- }
- function positionDragY(destY, animate) {
- if (!isScrollableV) {
- return;
- }
- if (destY < 0) {
- destY = 0;
- } else if (destY > dragMaxY) {
- destY = dragMaxY;
- }
- // allow for devs to prevent the JSP from being scrolled
- var willScrollYEvent = new $.Event("jsp-will-scroll-y");
- elem.trigger(willScrollYEvent, [destY]);
- if (willScrollYEvent.isDefaultPrevented()) {
- return;
- }
- var tmpVerticalDragPosition = destY || 0;
- var isAtTop = tmpVerticalDragPosition === 0,
- isAtBottom = tmpVerticalDragPosition == dragMaxY,
- percentScrolled = destY / dragMaxY,
- destTop = -percentScrolled * (contentHeight - paneHeight);
- // can't just check if(animate) because false is a valid value that could be passed in...
- if (animate === undefined) {
- animate = settings.animateScroll;
- }
- if (animate) {
- jsp.animate(verticalDrag, 'top', destY, _positionDragY, function () {
- elem.trigger('jsp-user-scroll-y', [-destTop, isAtTop, isAtBottom]);
- });
- } else {
- verticalDrag.css('top', destY);
- _positionDragY(destY);
- elem.trigger('jsp-user-scroll-y', [-destTop, isAtTop, isAtBottom]);
- }
- }
- function _positionDragY(destY) {
- if (destY === undefined) {
- destY = verticalDrag.position().top;
- }
- container.scrollTop(0);
- verticalDragPosition = destY || 0;
- var isAtTop = verticalDragPosition === 0,
- isAtBottom = verticalDragPosition == dragMaxY,
- percentScrolled = destY / dragMaxY,
- destTop = -percentScrolled * (contentHeight - paneHeight);
- if (wasAtTop != isAtTop || wasAtBottom != isAtBottom) {
- wasAtTop = isAtTop;
- wasAtBottom = isAtBottom;
- elem.trigger('jsp-arrow-change', [wasAtTop, wasAtBottom, wasAtLeft, wasAtRight]);
- }
- updateVerticalArrows(isAtTop, isAtBottom);
- pane.css('top', destTop);
- elem.trigger('jsp-scroll-y', [-destTop, isAtTop, isAtBottom]).trigger('scroll');
- }
- function positionDragX(destX, animate) {
- if (!isScrollableH) {
- return;
- }
- if (destX < 0) {
- destX = 0;
- } else if (destX > dragMaxX) {
- destX = dragMaxX;
- }
- // allow for devs to prevent the JSP from being scrolled
- var willScrollXEvent = new $.Event("jsp-will-scroll-x");
- elem.trigger(willScrollXEvent, [destX]);
- if (willScrollXEvent.isDefaultPrevented()) {
- return;
- }
- var tmpHorizontalDragPosition = destX || 0;
- var isAtLeft = tmpHorizontalDragPosition === 0,
- isAtRight = tmpHorizontalDragPosition == dragMaxX,
- percentScrolled = destX / dragMaxX,
- destLeft = -percentScrolled * (contentWidth - paneWidth);
- if (animate === undefined) {
- animate = settings.animateScroll;
- }
- if (animate) {
- jsp.animate(horizontalDrag, 'left', destX, _positionDragX, function () {
- elem.trigger('jsp-user-scroll-x', [-destLeft, isAtLeft, isAtRight]);
- });
- } else {
- horizontalDrag.css('left', destX);
- _positionDragX(destX);
- elem.trigger('jsp-user-scroll-x', [-destLeft, isAtLeft, isAtRight]);
- }
- }
- function _positionDragX(destX) {
- if (destX === undefined) {
- destX = horizontalDrag.position().left;
- }
- container.scrollTop(0);
- horizontalDragPosition = destX || 0;
- var isAtLeft = horizontalDragPosition === 0,
- isAtRight = horizontalDragPosition == dragMaxX,
- percentScrolled = destX / dragMaxX,
- destLeft = -percentScrolled * (contentWidth - paneWidth);
- if (wasAtLeft != isAtLeft || wasAtRight != isAtRight) {
- wasAtLeft = isAtLeft;
- wasAtRight = isAtRight;
- elem.trigger('jsp-arrow-change', [wasAtTop, wasAtBottom, wasAtLeft, wasAtRight]);
- }
- updateHorizontalArrows(isAtLeft, isAtRight);
- pane.css('left', destLeft);
- elem.trigger('jsp-scroll-x', [-destLeft, isAtLeft, isAtRight]).trigger('scroll');
- }
- function updateVerticalArrows(isAtTop, isAtBottom) {
- if (settings.showArrows) {
- arrowUp[isAtTop ? 'addClass' : 'removeClass']('jspDisabled');
- arrowDown[isAtBottom ? 'addClass' : 'removeClass']('jspDisabled');
- }
- }
- function updateHorizontalArrows(isAtLeft, isAtRight) {
- if (settings.showArrows) {
- arrowLeft[isAtLeft ? 'addClass' : 'removeClass']('jspDisabled');
- arrowRight[isAtRight ? 'addClass' : 'removeClass']('jspDisabled');
- }
- }
- function scrollToY(destY, animate) {
- var percentScrolled = destY / (contentHeight - paneHeight);
- positionDragY(percentScrolled * dragMaxY, animate);
- }
- function scrollToX(destX, animate) {
- var percentScrolled = destX / (contentWidth - paneWidth);
- positionDragX(percentScrolled * dragMaxX, animate);
- }
- function scrollToElement(ele, stickToTop, animate) {
- var e, eleHeight, eleWidth, eleTop = 0, eleLeft = 0, viewportTop, viewportLeft, maxVisibleEleTop,
- maxVisibleEleLeft, destY, destX;
- // Legal hash values aren't necessarily legal jQuery selectors so we need to catch any
- // errors from the lookup...
- try {
- e = $(ele);
- } catch (err) {
- return;
- }
- eleHeight = e.outerHeight();
- eleWidth = e.outerWidth();
- container.scrollTop(0);
- container.scrollLeft(0);
- // loop through parents adding the offset top of any elements that are relatively positioned between
- // the focused element and the jspPane so we can get the true distance from the top
- // of the focused element to the top of the scrollpane...
- while (!e.is('.jspPane')) {
- eleTop += e.position().top;
- eleLeft += e.position().left;
- e = e.offsetParent();
- if (/^body|html$/i.test(e[0].nodeName)) {
- // we ended up too high in the document structure. Quit!
- return;
- }
- }
- viewportTop = contentPositionY();
- maxVisibleEleTop = viewportTop + paneHeight;
- if (eleTop < viewportTop || stickToTop) { // element is above viewport
- destY = eleTop - settings.horizontalGutter;
- } else if (eleTop + eleHeight > maxVisibleEleTop) { // element is below viewport
- destY = eleTop - paneHeight + eleHeight + settings.horizontalGutter;
- }
- if (!isNaN(destY)) {
- scrollToY(destY, animate);
- }
- viewportLeft = contentPositionX();
- maxVisibleEleLeft = viewportLeft + paneWidth;
- if (eleLeft < viewportLeft || stickToTop) { // element is to the left of viewport
- destX = eleLeft - settings.horizontalGutter;
- } else if (eleLeft + eleWidth > maxVisibleEleLeft) { // element is to the right viewport
- destX = eleLeft - paneWidth + eleWidth + settings.horizontalGutter;
- }
- if (!isNaN(destX)) {
- scrollToX(destX, animate);
- }
- }
- function contentPositionX() {
- return -pane.position().left;
- }
- function contentPositionY() {
- return -pane.position().top;
- }
- function isCloseToBottom() {
- var scrollableHeight = contentHeight - paneHeight;
- return (scrollableHeight > 20) && (scrollableHeight - contentPositionY() < 10);
- }
- function isCloseToRight() {
- var scrollableWidth = contentWidth - paneWidth;
- return (scrollableWidth > 20) && (scrollableWidth - contentPositionX() < 10);
- }
- function initMousewheel() {
- container.off(mwEvent).on(
- mwEvent,
- function (event, delta, deltaX, deltaY) {
- if (!horizontalDragPosition) horizontalDragPosition = 0;
- if (!verticalDragPosition) verticalDragPosition = 0;
- var dX = horizontalDragPosition, dY = verticalDragPosition,
- factor = event.deltaFactor || settings.mouseWheelSpeed;
- jsp.scrollBy(deltaX * factor, -deltaY * factor, false);
- // return true if there was no movement so rest of screen can scroll
- return dX == horizontalDragPosition && dY == verticalDragPosition;
- }
- );
- }
- function removeMousewheel() {
- container.off(mwEvent);
- }
- function nil() {
- return false;
- }
- function initFocusHandler() {
- pane.find(':input,a').off('focus.jsp').on(
- 'focus.jsp',
- function (e) {
- scrollToElement(e.target, false);
- }
- );
- }
- function removeFocusHandler() {
- pane.find(':input,a').off('focus.jsp');
- }
- function initKeyboardNav() {
- var keyDown, elementHasScrolled, validParents = [];
- if (isScrollableH) {
- validParents.push(horizontalBar[0]);
- }
- if (isScrollableV) {
- validParents.push(verticalBar[0]);
- }
- // IE also focuses elements that don't have tabindex set.
- pane.on(
- 'focus.jsp',
- function () {
- elem.focus();
- }
- );
- elem.attr('tabindex', 0)
- .off('keydown.jsp keypress.jsp')
- .on(
- 'keydown.jsp',
- function (e) {
- if (e.target !== this && !(validParents.length && $(e.target).closest(validParents).length)) {
- return;
- }
- var dX = horizontalDragPosition, dY = verticalDragPosition;
- switch (e.keyCode) {
- case 40: // down
- case 38: // up
- case 34: // page down
- case 32: // space
- case 33: // page up
- case 39: // right
- case 37: // left
- keyDown = e.keyCode;
- keyDownHandler();
- break;
- case 35: // end
- scrollToY(contentHeight - paneHeight);
- keyDown = null;
- break;
- case 36: // home
- scrollToY(0);
- keyDown = null;
- break;
- }
- elementHasScrolled = e.keyCode == keyDown && dX != horizontalDragPosition || dY != verticalDragPosition;
- return !elementHasScrolled;
- }
- ).on(
- 'keypress.jsp', // For FF/ OSX so that we can cancel the repeat key presses if the JSP scrolls...
- function (e) {
- if (e.keyCode == keyDown) {
- keyDownHandler();
- }
- // If the keypress is not related to the area, ignore it. Fixes problem with inputs inside scrolled area. Copied from line 955.
- if (e.target !== this && !(validParents.length && $(e.target).closest(validParents).length)) {
- return;
- }
- return !elementHasScrolled;
- }
- );
- if (settings.hideFocus) {
- elem.css('outline', 'none');
- if ('hideFocus' in container[0]) {
- elem.attr('hideFocus', true);
- }
- } else {
- elem.css('outline', '');
- if ('hideFocus' in container[0]) {
- elem.attr('hideFocus', false);
- }
- }
- function keyDownHandler() {
- var dX = horizontalDragPosition, dY = verticalDragPosition;
- switch (keyDown) {
- case 40: // down
- jsp.scrollByY(settings.keyboardSpeed, false);
- break;
- case 38: // up
- jsp.scrollByY(-settings.keyboardSpeed, false);
- break;
- case 34: // page down
- case 32: // space
- jsp.scrollByY(paneHeight * settings.scrollPagePercent, false);
- break;
- case 33: // page up
- jsp.scrollByY(-paneHeight * settings.scrollPagePercent, false);
- break;
- case 39: // right
- jsp.scrollByX(settings.keyboardSpeed, false);
- break;
- case 37: // left
- jsp.scrollByX(-settings.keyboardSpeed, false);
- break;
- }
- elementHasScrolled = dX != horizontalDragPosition || dY != verticalDragPosition;
- return elementHasScrolled;
- }
- }
- function removeKeyboardNav() {
- elem.attr('tabindex', '-1')
- .removeAttr('tabindex')
- .off('keydown.jsp keypress.jsp');
- pane.off('.jsp');
- }
- function observeHash() {
- if (location.hash && location.hash.length > 1) {
- var e,
- retryInt,
- hash = escape(location.hash.substr(1)) // hash must be escaped to prevent XSS
- ;
- try {
- e = $('#' + hash + ', a[name="' + hash + '"]');
- } catch (err) {
- return;
- }
- if (e.length && pane.find(hash)) {
- // nasty workaround but it appears to take a little while before the hash has done its thing
- // to the rendered page so we just wait until the container's scrollTop has been messed up.
- if (container.scrollTop() === 0) {
- retryInt = setInterval(
- function () {
- if (container.scrollTop() > 0) {
- scrollToElement(e, true);
- $(document).scrollTop(container.position().top);
- clearInterval(retryInt);
- }
- },
- 50
- );
- } else {
- scrollToElement(e, true);
- $(document).scrollTop(container.position().top);
- }
- }
- }
- }
- function hijackInternalLinks() {
- // only register the link handler once
- if ($(document.body).data('jspHijack')) {
- return;
- }
- // remember that the handler was bound
- $(document.body).data('jspHijack', true);
- // use live handler to also capture newly created links
- $(document.body).delegate('a[href*="#"]', 'click', function (event) {
- // does the link point to the same page?
- // this also takes care of cases with a <base>-Tag or Links not starting with the hash #
- // e.g. <a href="index.html#test"> when the current url already is index.html
- var href = this.href.substr(0, this.href.indexOf('#')),
- locationHref = location.href,
- hash,
- element,
- container,
- jsp,
- scrollTop,
- elementTop;
- if (location.href.indexOf('#') !== -1) {
- locationHref = location.href.substr(0, location.href.indexOf('#'));
- }
- if (href !== locationHref) {
- // the link points to another page
- return;
- }
- // check if jScrollPane should handle this click event
- hash = escape(this.href.substr(this.href.indexOf('#') + 1));
- // find the element on the page
- try {
- element = $('#' + hash + ', a[name="' + hash + '"]');
- } catch (e) {
- // hash is not a valid jQuery identifier
- return;
- }
- if (!element.length) {
- // this link does not point to an element on this page
- return;
- }
- container = element.closest('.jspScrollable');
- jsp = container.data('jsp');
- // jsp might be another jsp instance than the one, that bound this event
- // remember: this event is only bound once for all instances.
- jsp.scrollToElement(element, true);
- if (container[0].scrollIntoView) {
- // also scroll to the top of the container (if it is not visible)
- scrollTop = $(window).scrollTop();
- elementTop = element.offset().top;
- if (elementTop < scrollTop || elementTop > scrollTop + $(window).height()) {
- container[0].scrollIntoView();
- }
- }
- // jsp handled this event, prevent the browser default (scrolling :P)
- event.preventDefault();
- });
- }
- // Init touch on iPad, iPhone, iPod, Android
- function initTouch() {
- var startX,
- startY,
- touchStartX,
- touchStartY,
- moved,
- moving = false;
- container.off('touchstart.jsp touchmove.jsp touchend.jsp click.jsp-touchclick').on(
- 'touchstart.jsp',
- function (e) {
- var touch = e.originalEvent.touches[0];
- startX = contentPositionX();
- startY = contentPositionY();
- touchStartX = touch.pageX;
- touchStartY = touch.pageY;
- moved = false;
- moving = true;
- }
- ).on(
- 'touchmove.jsp',
- function (ev) {
- if (!moving) {
- return;
- }
- var touchPos = ev.originalEvent.touches[0],
- dX = horizontalDragPosition, dY = verticalDragPosition;
- jsp.scrollTo(startX + touchStartX - touchPos.pageX, startY + touchStartY - touchPos.pageY);
- moved = moved || Math.abs(touchStartX - touchPos.pageX) > 5 || Math.abs(touchStartY - touchPos.pageY) > 5;
- // return true if there was no movement so rest of screen can scroll
- return dX == horizontalDragPosition && dY == verticalDragPosition;
- }
- ).on(
- 'touchend.jsp',
- function (e) {
- moving = false;
- /*if(moved) {
- return false;
- }*/
- }
- ).on(
- 'click.jsp-touchclick',
- function (e) {
- if (moved) {
- moved = false;
- return false;
- }
- }
- );
- }
- function destroy() {
- var currentY = contentPositionY(),
- currentX = contentPositionX();
- elem.removeClass('jspScrollable').off('.jsp');
- pane.off('.jsp');
- elem.replaceWith(originalElement.append(pane.children()));
- originalElement.scrollTop(currentY);
- originalElement.scrollLeft(currentX);
- // clear reinitialize timer if active
- if (reinitialiseInterval) {
- clearInterval(reinitialiseInterval);
- }
- }
- // Public API
- $.extend(
- jsp,
- {
- // Reinitialises the scroll pane (if it's internal dimensions have changed since the last time it
- // was initialised). The settings object which is passed in will override any settings from the
- // previous time it was initialised - if you don't pass any settings then the ones from the previous
- // initialisation will be used.
- reinitialise: function (s) {
- s = $.extend({}, settings, s);
- initialise(s);
- },
- // Scrolls the specified element (a jQuery object, DOM node or jQuery selector string) into view so
- // that it can be seen within the viewport. If stickToTop is true then the element will appear at
- // the top of the viewport, if it is false then the viewport will scroll as little as possible to
- // show the element. You can also specify if you want animation to occur. If you don't provide this
- // argument then the animateScroll value from the settings object is used instead.
- scrollToElement: function (ele, stickToTop, animate) {
- scrollToElement(ele, stickToTop, animate);
- },
- // Scrolls the pane so that the specified co-ordinates within the content are at the top left
- // of the viewport. animate is optional and if not passed then the value of animateScroll from
- // the settings object this jScrollPane was initialised with is used.
- scrollTo: function (destX, destY, animate) {
- scrollToX(destX, animate);
- scrollToY(destY, animate);
- },
- // Scrolls the pane so that the specified co-ordinate within the content is at the left of the
- // viewport. animate is optional and if not passed then the value of animateScroll from the settings
- // object this jScrollPane was initialised with is used.
- scrollToX: function (destX, animate) {
- scrollToX(destX, animate);
- },
- // Scrolls the pane so that the specified co-ordinate within the content is at the top of the
- // viewport. animate is optional and if not passed then the value of animateScroll from the settings
- // object this jScrollPane was initialised with is used.
- scrollToY: function (destY, animate) {
- scrollToY(destY, animate);
- },
- // Scrolls the pane to the specified percentage of its maximum horizontal scroll position. animate
- // is optional and if not passed then the value of animateScroll from the settings object this
- // jScrollPane was initialised with is used.
- scrollToPercentX: function (destPercentX, animate) {
- scrollToX(destPercentX * (contentWidth - paneWidth), animate);
- },
- // Scrolls the pane to the specified percentage of its maximum vertical scroll position. animate
- // is optional and if not passed then the value of animateScroll from the settings object this
- // jScrollPane was initialised with is used.
- scrollToPercentY: function (destPercentY, animate) {
- scrollToY(destPercentY * (contentHeight - paneHeight), animate);
- },
- // Scrolls the pane by the specified amount of pixels. animate is optional and if not passed then
- // the value of animateScroll from the settings object this jScrollPane was initialised with is used.
- scrollBy: function (deltaX, deltaY, animate) {
- jsp.scrollByX(deltaX, animate);
- jsp.scrollByY(deltaY, animate);
- },
- // Scrolls the pane by the specified amount of pixels. animate is optional and if not passed then
- // the value of animateScroll from the settings object this jScrollPane was initialised with is used.
- scrollByX: function (deltaX, animate) {
- var destX = contentPositionX() + Math[deltaX < 0 ? 'floor' : 'ceil'](deltaX),
- percentScrolled = destX / (contentWidth - paneWidth);
- positionDragX(percentScrolled * dragMaxX, animate);
- },
- // Scrolls the pane by the specified amount of pixels. animate is optional and if not passed then
- // the value of animateScroll from the settings object this jScrollPane was initialised with is used.
- scrollByY: function (deltaY, animate) {
- var destY = contentPositionY() + Math[deltaY < 0 ? 'floor' : 'ceil'](deltaY),
- percentScrolled = destY / (contentHeight - paneHeight);
- positionDragY(percentScrolled * dragMaxY, animate);
- },
- // Positions the horizontal drag at the specified x position (and updates the viewport to reflect
- // this). animate is optional and if not passed then the value of animateScroll from the settings
- // object this jScrollPane was initialised with is used.
- positionDragX: function (x, animate) {
- positionDragX(x, animate);
- },
- // Positions the vertical drag at the specified y position (and updates the viewport to reflect
- // this). animate is optional and if not passed then the value of animateScroll from the settings
- // object this jScrollPane was initialised with is used.
- positionDragY: function (y, animate) {
- positionDragY(y, animate);
- },
- // This method is called when jScrollPane is trying to animate to a new position. You can override
- // it if you want to provide advanced animation functionality. It is passed the following arguments:
- // * ele - the element whose position is being animated
- // * prop - the property that is being animated
- // * value - the value it's being animated to
- // * stepCallback - a function that you must execute each time you update the value of the property
- // * completeCallback - a function that will be executed after the animation had finished
- // You can use the default implementation (below) as a starting point for your own implementation.
- animate: function (ele, prop, value, stepCallback, completeCallback) {
- var params = {};
- params[prop] = value;
- ele.animate(
- params,
- {
- 'duration': settings.animateDuration,
- 'easing': settings.animateEase,
- 'queue': false,
- 'step': stepCallback,
- 'complete': completeCallback
- }
- );
- },
- // Returns the current x position of the viewport with regards to the content pane.
- getContentPositionX: function () {
- return contentPositionX();
- },
- // Returns the current y position of the viewport with regards to the content pane.
- getContentPositionY: function () {
- return contentPositionY();
- },
- // Returns the width of the content within the scroll pane.
- getContentWidth: function () {
- return contentWidth;
- },
- // Returns the height of the content within the scroll pane.
- getContentHeight: function () {
- return contentHeight;
- },
- // Returns the horizontal position of the viewport within the pane content.
- getPercentScrolledX: function () {
- return contentPositionX() / (contentWidth - paneWidth);
- },
- // Returns the vertical position of the viewport within the pane content.
- getPercentScrolledY: function () {
- return contentPositionY() / (contentHeight - paneHeight);
- },
- // Returns whether or not this scrollpane has a horizontal scrollbar.
- getIsScrollableH: function () {
- return isScrollableH;
- },
- // Returns whether or not this scrollpane has a vertical scrollbar.
- getIsScrollableV: function () {
- return isScrollableV;
- },
- // Gets a reference to the content pane. It is important that you use this method if you want to
- // edit the content of your jScrollPane as if you access the element directly then you may have some
- // problems (as your original element has had additional elements for the scrollbars etc added into
- // it).
- getContentPane: function () {
- return pane;
- },
- // Scrolls this jScrollPane down as far as it can currently scroll. If animate isn't passed then the
- // animateScroll value from settings is used instead.
- scrollToBottom: function (animate) {
- positionDragY(dragMaxY, animate);
- },
- // Hijacks the links on the page which link to content inside the scrollpane. If you have changed
- // the content of your page (e.g. via AJAX) and want to make sure any new anchor links to the
- // contents of your scroll pane will work then call this function.
- hijackInternalLinks: $.noop,
- // Removes the jScrollPane and returns the page to the state it was in before jScrollPane was
- // initialised.
- destroy: function () {
- destroy();
- }
- }
- );
- initialise(s);
- }
- // Pluginifying code...
- settings = $.extend({}, $.fn.jScrollPane.defaults, settings);
- // Apply default speed
- $.each(['arrowButtonSpeed', 'trackClickSpeed', 'keyboardSpeed'], function () {
- settings[this] = settings[this] || settings.speed;
- });
- return this.each(
- function () {
- var elem = $(this), jspApi = elem.data('jsp');
- if (jspApi) {
- jspApi.reinitialise(settings);
- } else {
- $("script", elem).filter('[type="text/javascript"],:not([type])').remove();
- jspApi = new JScrollPane(elem, settings);
- elem.data('jsp', jspApi);
- }
- }
- );
- };
- $.fn.jScrollPane.defaults = {
- showArrows: false,
- maintainPosition: true,
- stickToBottom: false,
- stickToRight: false,
- clickOnTrack: true,
- autoReinitialise: false,
- autoReinitialiseDelay: 500,
- verticalDragMinHeight: 0,
- verticalDragMaxHeight: 99999,
- horizontalDragMinWidth: 0,
- horizontalDragMaxWidth: 99999,
- contentWidth: undefined,
- animateScroll: false,
- animateDuration: 300,
- animateEase: 'linear',
- hijackInternalLinks: false,
- verticalGutter: 4,
- horizontalGutter: 4,
- mouseWheelSpeed: 3,
- arrowButtonSpeed: 0,
- arrowRepeatFreq: 50,
- arrowScrollOnHover: false,
- trackClickSpeed: 0,
- trackClickRepeatFreq: 70,
- verticalArrowPositions: 'split',
- horizontalArrowPositions: 'split',
- enableKeyboardNavigation: true,
- hideFocus: false,
- keyboardSpeed: 0,
- initialDelay: 300, // Delay before starting repeating
- speed: 30, // Default speed when others falsey
- scrollPagePercent: 0.8, // Percent of visible area scrolled when pageUp/Down or track area pressed
- alwaysShowVScroll: false,
- alwaysShowHScroll: false,
- resizeSensor: false,
- resizeSensorDelay: 0,
- };
- }));
|