github.com/apremalal/vamps-core@v1.0.1-0.20161221121535-d430b56ec174/server/webapps/app/base/plugins/jquery-slimscroll/jquery.slimscroll.js (about)

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