Current File : /home/inlingua/www/sensoriumpsychologists.com/student/plugins/slimScroll/jquery.slimscroll.js
/*! 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,

          //Fix for IE10

          "-ms-touch-action": "none"

        });



        // 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();

        });



        if (window.navigator.msPointerEnabled) {          

          // support for mobile

          me.bind('MSPointerDown', function (e, b) {

            if (e.originalEvent.targetTouches.length)

            {

              // record where touch started

              touchDif = e.originalEvent.targetTouches[0].pageY;

            }

          });



          me.bind('MSPointerMove', function (e) {

            // prevent scrolling the page if necessary

            e.originalEvent.preventDefault();

            if (e.originalEvent.targetTouches.length)

            {

              // see how far user swiped

              var diff = (touchDif - e.originalEvent.targetTouches[0].pageY) / o.touchScrollStep;

              // scroll content

              scrollContent(diff, true);

              touchDif = e.originalEvent.targetTouches[0].pageY;

              

            }

          });

        } else {

          // 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);