JAVASCRIPT   72

jquery slimscroll

Guest on 3rd May 2022 09:56:44 AM

  1. /*!
  2. jquery.slimscroll.js
  3. Copyright (c) Piotr Rochala
  4.  * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
  5.  * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
  6.  *
  7.  * Version: 1.3.0
  8.  *
  9.  */
  10. (function($) {
  11.  
  12.   jQuery.fn.extend({
  13.     slimScroll: function(options) {
  14.  
  15.       var defaults = {
  16.  
  17.         // width in pixels of the visible scroll area
  18.         width : 'auto',
  19.  
  20.         // height in pixels of the visible scroll area
  21.         height : '250px',
  22.  
  23.         // width in pixels of the scrollbar and rail
  24.         size : '7px',
  25.  
  26.         // scrollbar color, accepts any hex/color value
  27.         color: '#000',
  28.  
  29.         // scrollbar position - left/right
  30.         position : 'right',
  31.  
  32.         // distance in pixels between the side edge and the scrollbar
  33.         distance : '1px',
  34.  
  35.         // default scroll position on load - top / bottom / $('selector')
  36.         start : 'top',
  37.  
  38.         // sets scrollbar opacity
  39.         opacity : .4,
  40.  
  41.         // enables always-on mode for the scrollbar
  42.         alwaysVisible : false,
  43.  
  44.         // check if we should hide the scrollbar when user is hovering over
  45.         disableFadeOut : false,
  46.  
  47.         // sets visibility of the rail
  48.         railVisible : false,
  49.  
  50.         // sets rail color
  51.         railColor : '#333',
  52.  
  53.         // sets rail opacity
  54.         railOpacity : .2,
  55.  
  56.         // whether  we should use jQuery UI Draggable to enable bar dragging
  57.         railDraggable : true,
  58.  
  59.         // defautlt CSS class of the slimscroll rail
  60.         railClass : 'slimScrollRail',
  61.  
  62.         // defautlt CSS class of the slimscroll bar
  63.         barClass : 'slimScrollBar',
  64.  
  65.         // defautlt CSS class of the slimscroll wrapper
  66.         wrapperClass : 'slimScrollDiv',
  67.  
  68.         // check if mousewheel should scroll the window if we reach top/bottom
  69.         allowPageScroll : false,
  70.  
  71.         // scroll amount applied to each mouse wheel step
  72.         wheelStep : 20,
  73.  
  74.         // scroll amount applied when user is using gestures
  75.         touchScrollStep : 200,
  76.  
  77.         // sets border radius
  78.         borderRadius: '7px',
  79.  
  80.         // sets border radius of the rail
  81.         railBorderRadius : '7px'
  82.       };
  83.  
  84.       var o = $.extend(defaults, options);
  85.  
  86.       // do it for every element that matches selector
  87.       this.each(function(){
  88.  
  89.       var isOverPanel, isOverBar, isDragg, queueHide, touchDif,
  90.         barHeight, percentScroll, lastScroll,
  91.         divS = '<div></div>',
  92.         minBarHeight = 30,
  93.         releaseScroll = false;
  94.  
  95.         // used in event handlers and for better minification
  96.         var me = $(this);
  97.  
  98.         // ensure we are not binding it again
  99.         if (me.parent().hasClass(o.wrapperClass))
  100.         {
  101.             // start from last bar position
  102.             var offset = me.scrollTop();
  103.  
  104.             // find bar and rail
  105.             bar = me.parent().find('.' + o.barClass);
  106.             rail = me.parent().find('.' + o.railClass);
  107.  
  108.             getBarHeight();
  109.  
  110.             // check if we should scroll existing instance
  111.             if ($.isPlainObject(options))
  112.             {
  113.               // Pass height: auto to an existing slimscroll object to force a resize after contents have changed
  114.               if ( 'height' in options && options.height == 'auto' ) {
  115.                 me.parent().css('height', 'auto');
  116.                 me.css('height', 'auto');
  117.                 var height = me.parent().parent().height();
  118.                 me.parent().css('height', height);
  119.                 me.css('height', height);
  120.               }
  121.  
  122.               if ('scrollTo' in options)
  123.               {
  124.                 // jump to a static point
  125.                 offset = parseInt(o.scrollTo);
  126.               }
  127.               else if ('scrollBy' in options)
  128.               {
  129.                 // jump by value pixels
  130.                 offset += parseInt(o.scrollBy);
  131.               }
  132.               else if ('destroy' in options)
  133.               {
  134.                 // remove slimscroll elements
  135.                 bar.remove();
  136.                 rail.remove();
  137.                 me.unwrap();
  138.                 return;
  139.               }
  140.  
  141.               // scroll content by the given offset
  142.               scrollContent(offset, false, true);
  143.             }
  144.  
  145.             return;
  146.         }
  147.  
  148.         // optionally set height to the parent's height
  149.         o.height = (o.height == 'auto') ? me.parent().height() : o.height;
  150.  
  151.         // wrap content
  152.         var wrapper = $(divS)
  153.           .addClass(o.wrapperClass)
  154.           .css({
  155.             position: 'relative',
  156.             overflow: 'hidden',
  157.             width: o.width,
  158.             height: o.height
  159.           });
  160.  
  161.         // update style for the div
  162.         me.css({
  163.           overflow: 'hidden',
  164.           width: o.width,
  165.           height: o.height
  166.         });
  167.  
  168.         // create scrollbar rail
  169.         var rail = $(divS)
  170.           .addClass(o.railClass)
  171.           .css({
  172.             width: o.size,
  173.             height: '100%',
  174.             position: 'absolute',
  175.             top: 0,
  176.             display: (o.alwaysVisible && o.railVisible) ? 'block' : 'none',
  177.             'border-radius': o.railBorderRadius,
  178.             background: o.railColor,
  179.             opacity: o.railOpacity,
  180.             zIndex: 90
  181.           });
  182.  
  183.         // create scrollbar
  184.         var bar = $(divS)
  185.           .addClass(o.barClass)
  186.           .css({
  187.             background: o.color,
  188.             width: o.size,
  189.             position: 'absolute',
  190.             top: 0,
  191.             opacity: o.opacity,
  192.             display: o.alwaysVisible ? 'block' : 'none',
  193.             'border-radius' : o.borderRadius,
  194.             BorderRadius: o.borderRadius,
  195.             MozBorderRadius: o.borderRadius,
  196.             WebkitBorderRadius: o.borderRadius,
  197.             zIndex: 99
  198.           });
  199.  
  200.         // set position
  201.         var posCss = (o.position == 'right') ? { right: o.distance } : { left: o.distance };
  202.         rail.css(posCss);
  203.         bar.css(posCss);
  204.  
  205.         // wrap it
  206.         me.wrap(wrapper);
  207.  
  208.         // append to parent div
  209.         me.parent().append(bar);
  210.         me.parent().append(rail);
  211.  
  212.         // make it draggable and no longer dependent on the jqueryUI
  213.         if (o.railDraggable){
  214.           bar.bind("mousedown", function(e) {
  215.             var $doc = $(document);
  216.             isDragg = true;
  217.             t = parseFloat(bar.css('top'));
  218.             pageY = e.pageY;
  219.  
  220.             $doc.bind("mousemove.slimscroll", function(e){
  221.               currTop = t + e.pageY - pageY;
  222.               bar.css('top', currTop);
  223.               scrollContent(0, bar.position().top, false);// scroll content
  224.             });
  225.  
  226.             $doc.bind("mouseup.slimscroll", function(e) {
  227.               isDragg = false;hideBar();
  228.               $doc.unbind('.slimscroll');
  229.             });
  230.             return false;
  231.           }).bind("selectstart.slimscroll", function(e){
  232.             e.stopPropagation();
  233.             e.preventDefault();
  234.             return false;
  235.           });
  236.         }
  237.  
  238.         // on rail over
  239.         rail.hover(function(){
  240.           showBar();
  241.         }, function(){
  242.           hideBar();
  243.         });
  244.  
  245.         // on bar over
  246.         bar.hover(function(){
  247.           isOverBar = true;
  248.         }, function(){
  249.           isOverBar = false;
  250.         });
  251.  
  252.         // show on parent mouseover
  253.         me.hover(function(){
  254.           isOverPanel = true;
  255.           showBar();
  256.           hideBar();
  257.         }, function(){
  258.           isOverPanel = false;
  259.           hideBar();
  260.         });
  261.  
  262.         // support for mobile
  263.         me.bind('touchstart', function(e,b){
  264.           if (e.originalEvent.touches.length)
  265.           {
  266.             // record where touch started
  267.             touchDif = e.originalEvent.touches[0].pageY;
  268.           }
  269.         });
  270.  
  271.         me.bind('touchmove', function(e){
  272.           // prevent scrolling the page if necessary
  273.           if(!releaseScroll)
  274.           {
  275.                       e.originalEvent.preventDefault();
  276.                       }
  277.           if (e.originalEvent.touches.length)
  278.           {
  279.             // see how far user swiped
  280.             var diff = (touchDif - e.originalEvent.touches[0].pageY) / o.touchScrollStep;
  281.             // scroll content
  282.             scrollContent(diff, true);
  283.             touchDif = e.originalEvent.touches[0].pageY;
  284.           }
  285.         });
  286.  
  287.         // set up initial height
  288.         getBarHeight();
  289.  
  290.         // check start position
  291.         if (o.start === 'bottom')
  292.         {
  293.           // scroll content to bottom
  294.           bar.css({ top: me.outerHeight() - bar.outerHeight() });
  295.           scrollContent(0, true);
  296.         }
  297.         else if (o.start !== 'top')
  298.         {
  299.           // assume jQuery selector
  300.           scrollContent($(o.start).position().top, null, true);
  301.  
  302.           // make sure bar stays hidden
  303.           if (!o.alwaysVisible) { bar.hide(); }
  304.         }
  305.  
  306.         // attach scroll events
  307.         attachWheel();
  308.  
  309.         function _onWheel(e)
  310.         {
  311.           // use mouse wheel only when mouse is over
  312.           if (!isOverPanel) { return; }
  313.  
  314.           var e = e || window.event;
  315.  
  316.           var delta = 0;
  317.           if (e.wheelDelta) { delta = -e.wheelDelta/120; }
  318.           if (e.detail) { delta = e.detail / 3; }
  319.  
  320.           var target = e.target || e.srcTarget || e.srcElement;
  321.           if ($(target).closest('.' + o.wrapperClass).is(me.parent())) {
  322.             // scroll content
  323.             scrollContent(delta, true);
  324.           }
  325.  
  326.           // stop window scroll
  327.           if (e.preventDefault && !releaseScroll) { e.preventDefault(); }
  328.           if (!releaseScroll) { e.returnValue = false; }
  329.         }
  330.  
  331.         function scrollContent(y, isWheel, isJump)
  332.         {
  333.           releaseScroll = false;
  334.           var delta = y;
  335.           var maxTop = me.outerHeight() - bar.outerHeight();
  336.  
  337.           if (isWheel)
  338.           {
  339.             // move bar with mouse wheel
  340.             delta = parseInt(bar.css('top')) + y * parseInt(o.wheelStep) / 100 * bar.outerHeight();
  341.  
  342.             // move bar, make sure it doesn't go out
  343.             delta = Math.min(Math.max(delta, 0), maxTop);
  344.  
  345.             // if scrolling down, make sure a fractional change to the
  346.             // scroll position isn't rounded away when the scrollbar's CSS is set
  347.             // this flooring of delta would happened automatically when
  348.             // bar.css is set below, but we floor here for clarity
  349.             delta = (y > 0) ? Math.ceil(delta) : Math.floor(delta);
  350.  
  351.             // scroll the scrollbar
  352.             bar.css({ top: delta + 'px' });
  353.           }
  354.           // calculate actual scroll amount
  355.           percentScroll = parseInt(bar.css('top')) / (me.outerHeight() - bar.outerHeight());
  356.           delta = percentScroll * (me[0].scrollHeight - me.outerHeight());
  357.  
  358.           if (isJump)
  359.           {
  360.             delta = y;
  361.             var offsetTop = delta / me[0].scrollHeight * me.outerHeight();
  362.             offsetTop = Math.min(Math.max(offsetTop, 0), maxTop);
  363.             bar.css({ top: offsetTop + 'px' });
  364.           }
  365.           // scroll content
  366.           me.scrollTop(delta);
  367.  
  368.           // fire scrolling event
  369.           me.trigger('slimscrolling', ~~delta);
  370.  
  371.           // ensure bar is visible
  372.           showBar();
  373.           // trigger hide when scroll is stopped
  374.           hideBar();
  375.         }
  376.         function attachWheel()
  377.         {
  378.           if (window.addEventListener)
  379.           {
  380.             this.addEventListener('DOMMouseScroll', _onWheel, false );
  381.             this.addEventListener('mousewheel', _onWheel, false );
  382.             this.addEventListener('MozMousePixelScroll', _onWheel, false );
  383.           }
  384.           else
  385.           {
  386.             document.attachEvent("onmousewheel", _onWheel)
  387.           }
  388.         }
  389.         function getBarHeight()
  390.         {
  391.           // calculate scrollbar height and make sure it is not too small
  392.           barHeight = Math.max((me.outerHeight() / me[0].scrollHeight) * me.outerHeight(), minBarHeight);
  393.           bar.css({ height: barHeight + 'px' });
  394.  
  395.           // hide scrollbar if content is not long enough
  396.           var display = barHeight == me.outerHeight() ? 'none' : 'block';
  397.           bar.css({ display: display });
  398.         }
  399.  
  400.         function showBar()
  401.         {
  402.           // recalculate bar height
  403.           getBarHeight();
  404.           clearTimeout(queueHide);
  405.           // when bar reached top or bottom
  406.           if (percentScroll == ~~percentScroll)
  407.           {
  408.             //release wheel
  409.             releaseScroll = o.allowPageScroll;
  410.  
  411.             // publish approporiate event
  412.             if (lastScroll != percentScroll)
  413.             {
  414.                 var msg = (~~percentScroll == 0) ? 'top' : 'bottom';
  415.                 me.trigger('slimscroll', msg);
  416.             }
  417.           }
  418.           else
  419.           {
  420.             releaseScroll = false;
  421.           }
  422.           lastScroll = percentScroll;
  423.           // show only when required
  424.           if(barHeight >= me.outerHeight()) {
  425.             //allow window scroll
  426.             releaseScroll = true;
  427.             return;
  428.           }
  429.           bar.stop(true,true).fadeIn('fast');
  430.           if (o.railVisible) { rail.stop(true,true).fadeIn('fast'); }
  431.         }
  432.  
  433.         function hideBar()
  434.         {
  435.           // only hide when options allow it
  436.           if (!o.alwaysVisible)
  437.           {
  438.             queueHide = setTimeout(function(){
  439.               if (!(o.disableFadeOut && isOverPanel) && !isOverBar && !isDragg)
  440.               {
  441.                 bar.fadeOut('slow');
  442.                 rail.fadeOut('slow');
  443.               }
  444.             }, 1000);
  445.           }
  446.         }
  447.       });
  448.       // maintain chainability
  449.       return this;
  450.     }
  451.   });
  452.   jQuery.fn.extend({
  453.     slimscroll: jQuery.fn.slimScroll
  454.   });
  455. })(jQuery);

Raw Paste


Login or Register to edit or fork this paste. It's free.