| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470 | /*! Copyright (c) 2011 Piotr Rochala (http://rocha.la) * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses. * * Version: 1.3.3 * */(function($) {  $.fn.extend({    slimScroll: function(options) {      var defaults = {        // width in pixels of the visible scroll area        width : 'auto',        // height in pixels of the visible scroll area        height : '250px',        // width in pixels of the scrollbar and rail        size : '7px',        // scrollbar color, accepts any hex/color value        color: '#000',        // scrollbar position - left/right        position : 'right',        // distance in pixels between the side edge and the scrollbar        distance : '1px',        // default scroll position on load - top / bottom / $('selector')        start : 'top',        // sets scrollbar opacity        opacity : .4,        // enables always-on mode for the scrollbar        alwaysVisible : false,        // check if we should hide the scrollbar when user is hovering over        disableFadeOut : false,        // sets visibility of the rail        railVisible : false,        // sets rail color        railColor : '#333',        // sets rail opacity        railOpacity : .2,        // whether  we should use jQuery UI Draggable to enable bar dragging        railDraggable : true,        // defautlt CSS class of the slimscroll rail        railClass : 'slimScrollRail',        // defautlt CSS class of the slimscroll bar        barClass : 'slimScrollBar',        // defautlt CSS class of the slimscroll wrapper        wrapperClass : 'slimScrollDiv',        // check if mousewheel should scroll the window if we reach top/bottom        allowPageScroll : false,        // scroll amount applied to each mouse wheel step        wheelStep : 20,        // scroll amount applied when user is using gestures        touchScrollStep : 200,        // sets border radius        borderRadius: '7px',        // sets border radius of the rail        railBorderRadius : '7px'      };      var o = $.extend(defaults, options);      // do it for every element that matches selector      this.each(function(){      var isOverPanel, isOverBar, isDragg, queueHide, touchDif,        barHeight, percentScroll, lastScroll,        divS = '<div></div>',        minBarHeight = 30,        releaseScroll = false;        // used in event handlers and for better minification        var me = $(this);        // ensure we are not binding it again        if (me.parent().hasClass(o.wrapperClass))        {            // start from last bar position            var offset = me.scrollTop();            // find bar and rail            bar = me.parent().find('.' + o.barClass);            rail = me.parent().find('.' + o.railClass);            getBarHeight();            // check if we should scroll existing instance            if ($.isPlainObject(options))            {              // Pass height: auto to an existing slimscroll object to force a resize after contents have changed              if ( 'height' in options && options.height == 'auto' ) {                me.parent().css('height', 'auto');                me.css('height', 'auto');                var height = me.parent().parent().height();                me.parent().css('height', height);                me.css('height', height);              }              if ('scrollTo' in options)              {                // jump to a static point                offset = parseInt(o.scrollTo);              }              else if ('scrollBy' in options)              {                // jump by value pixels                offset += parseInt(o.scrollBy);              }              else if ('destroy' in options)              {                // remove slimscroll elements                bar.remove();                rail.remove();                me.unwrap();                return;              }              // scroll content by the given offset              scrollContent(offset, false, true);            }            return;        }        else if ($.isPlainObject(options))        {            if ('destroy' in options)            {            	return;            }        }        // optionally set height to the parent's height        o.height = (o.height == 'auto') ? me.parent().height() : o.height;        // wrap content        var wrapper = $(divS)          .addClass(o.wrapperClass)          .css({            position: 'relative',            overflow: 'hidden',            width: o.width,            height: o.height          });        // update style for the div        me.css({          overflow: 'hidden',          width: o.width,          height: o.height        });        // create scrollbar rail        var rail = $(divS)          .addClass(o.railClass)          .css({            width: o.size,            height: '100%',            position: 'absolute',            top: 0,            display: (o.alwaysVisible && o.railVisible) ? 'block' : 'none',            'border-radius': o.railBorderRadius,            background: o.railColor,            opacity: o.railOpacity,            zIndex: 90          });        // create scrollbar        var bar = $(divS)          .addClass(o.barClass)          .css({            background: o.color,            width: o.size,            position: 'absolute',            top: 0,            opacity: o.opacity,            display: o.alwaysVisible ? 'block' : 'none',            'border-radius' : o.borderRadius,            BorderRadius: o.borderRadius,            MozBorderRadius: o.borderRadius,            WebkitBorderRadius: o.borderRadius,            zIndex: 99          });        // set position        var posCss = (o.position == 'right') ? { right: o.distance } : { left: o.distance };        rail.css(posCss);        bar.css(posCss);        // wrap it        me.wrap(wrapper);        // append to parent div        me.parent().append(bar);        me.parent().append(rail);        // make it draggable and no longer dependent on the jqueryUI        if (o.railDraggable){          bar.bind("mousedown", function(e) {            var $doc = $(document);            isDragg = true;            t = parseFloat(bar.css('top'));            pageY = e.pageY;            $doc.bind("mousemove.slimscroll", function(e){              currTop = t + e.pageY - pageY;              bar.css('top', currTop);              scrollContent(0, bar.position().top, false);// scroll content            });            $doc.bind("mouseup.slimscroll", function(e) {              isDragg = false;hideBar();              $doc.unbind('.slimscroll');            });            return false;          }).bind("selectstart.slimscroll", function(e){            e.stopPropagation();            e.preventDefault();            return false;          });        }        // on rail over        rail.hover(function(){          showBar();        }, function(){          hideBar();        });        // on bar over        bar.hover(function(){          isOverBar = true;        }, function(){          isOverBar = false;        });        // show on parent mouseover        me.hover(function(){          isOverPanel = true;          showBar();          hideBar();        }, function(){          isOverPanel = false;          hideBar();        });        // support for mobile        me.bind('touchstart', function(e,b){          if (e.originalEvent.touches.length)          {            // record where touch started            touchDif = e.originalEvent.touches[0].pageY;          }        });        me.bind('touchmove', function(e){          // prevent scrolling the page if necessary          if(!releaseScroll)          {  		      e.originalEvent.preventDefault();		      }          if (e.originalEvent.touches.length)          {            // see how far user swiped            var diff = (touchDif - e.originalEvent.touches[0].pageY) / o.touchScrollStep;            // scroll content            scrollContent(diff, true);            touchDif = e.originalEvent.touches[0].pageY;          }        });        // set up initial height        getBarHeight();        // check start position        if (o.start === 'bottom')        {          // scroll content to bottom          bar.css({ top: me.outerHeight() - bar.outerHeight() });          scrollContent(0, true);        }        else if (o.start !== 'top')        {          // assume jQuery selector          scrollContent($(o.start).position().top, null, true);          // make sure bar stays hidden          if (!o.alwaysVisible) { bar.hide(); }        }        // attach scroll events        attachWheel();        function _onWheel(e)        {          // use mouse wheel only when mouse is over          if (!isOverPanel) { return; }          var e = e || window.event;          var delta = 0;          if (e.wheelDelta) { delta = -e.wheelDelta/120; }          if (e.detail) { delta = e.detail / 3; }          var target = e.target || e.srcTarget || e.srcElement;          if ($(target).closest('.' + o.wrapperClass).is(me.parent())) {            // scroll content            scrollContent(delta, true);          }          // stop window scroll          if (e.preventDefault && !releaseScroll) { e.preventDefault(); }          if (!releaseScroll) { e.returnValue = false; }        }        function scrollContent(y, isWheel, isJump)        {          releaseScroll = false;          var delta = y;          var maxTop = me.outerHeight() - bar.outerHeight();          if (isWheel)          {            // move bar with mouse wheel            delta = parseInt(bar.css('top')) + y * parseInt(o.wheelStep) / 100 * bar.outerHeight();            // move bar, make sure it doesn't go out            delta = Math.min(Math.max(delta, 0), maxTop);            // if scrolling down, make sure a fractional change to the            // scroll position isn't rounded away when the scrollbar's CSS is set            // this flooring of delta would happened automatically when            // bar.css is set below, but we floor here for clarity            delta = (y > 0) ? Math.ceil(delta) : Math.floor(delta);            // scroll the scrollbar            bar.css({ top: delta + 'px' });          }          // calculate actual scroll amount          percentScroll = parseInt(bar.css('top')) / (me.outerHeight() - bar.outerHeight());          delta = percentScroll * (me[0].scrollHeight - me.outerHeight());          if (isJump)          {            delta = y;            var offsetTop = delta / me[0].scrollHeight * me.outerHeight();            offsetTop = Math.min(Math.max(offsetTop, 0), maxTop);            bar.css({ top: offsetTop + 'px' });          }          // scroll content          me.scrollTop(delta);          // fire scrolling event          me.trigger('slimscrolling', ~~delta);          // ensure bar is visible          showBar();          // trigger hide when scroll is stopped          hideBar();        }        function attachWheel()        {          if (window.addEventListener)          {            this.addEventListener('DOMMouseScroll', _onWheel, false );            this.addEventListener('mousewheel', _onWheel, false );          }          else          {            document.attachEvent("onmousewheel", _onWheel)          }        }        function getBarHeight()        {          // calculate scrollbar height and make sure it is not too small          barHeight = Math.max((me.outerHeight() / me[0].scrollHeight) * me.outerHeight(), minBarHeight);          bar.css({ height: barHeight + 'px' });          // hide scrollbar if content is not long enough          var display = barHeight == me.outerHeight() ? 'none' : 'block';          bar.css({ display: display });        }        function showBar()        {          // recalculate bar height          getBarHeight();          clearTimeout(queueHide);          // when bar reached top or bottom          if (percentScroll == ~~percentScroll)          {            //release wheel            releaseScroll = o.allowPageScroll;            // publish approporiate event            if (lastScroll != percentScroll)            {                var msg = (~~percentScroll == 0) ? 'top' : 'bottom';                me.trigger('slimscroll', msg);            }          }          else          {            releaseScroll = false;          }          lastScroll = percentScroll;          // show only when required          if(barHeight >= me.outerHeight()) {            //allow window scroll            releaseScroll = true;            return;          }          bar.stop(true,true).fadeIn('fast');          if (o.railVisible) { rail.stop(true,true).fadeIn('fast'); }        }        function hideBar()        {          // only hide when options allow it          if (!o.alwaysVisible)          {            queueHide = setTimeout(function(){              if (!(o.disableFadeOut && isOverPanel) && !isOverBar && !isDragg)              {                bar.fadeOut('slow');                rail.fadeOut('slow');              }            }, 1000);          }        }      });      // maintain chainability      return this;    }  });  $.fn.extend({    slimscroll: $.fn.slimScroll  });})(jQuery);
 |