diff --git a/README.md b/README.md index bc90347..f40a6a9 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,133 @@ slimScroll is a small jQuery plugin that transforms any div into a scrollable area with a nice scrollbar - similar to the one Facebook and Google started using in their products recently. slimScroll doesn't occupy any visual space as it only appears on a user initiated mouse-over. User can drag the scrollbar or use mouse-wheel to change the scroll value. -Demo and deocumentation available here: [jQuery slimScroll docs](http://rocha.la/jQuery-slimScroll) +##Documentation -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. \ No newline at end of file +Demo and documentation available here: [jQuery slimScroll docs](http://rocha.la/jQuery-slimScroll) + +###Example +``` + + +// Hook document ready event +$('document').ready(function(){ + // Initialise slimScroll + $(selector).slimScroll({ + height: '250px' + }); +}); +``` + +###Default Options + +| Options | Default | Type | Description | +| ----------------- | ----------------------| ----------------- | ---------------------------------------------------------------------- +| `allowPageScroll` | false | `boolean` | check if mousewheel should scroll the window if we reach top/bottom | +| `alwaysVisible` | false | `boolean` | enables always-on mode for the scrollbar | +| `animate` | false | `boolean` | sets animation status on a given scroll | +| `barClass` | 'slimScrollBar' | `string` | defautlt CSS class of the slimscroll bar | +| `barClassH` | 'slimScrollBarHor' | `string` | defautlt CSS class of the slimscroll bar (horizontal) | +| `barFixSize` | 0 | `number` | fixed bar height/width (set size in pixels | +| `borderRadius` | '7px' | `string[pixel]` | sets border radius | +| `color` | '#000' | `string[hex code]`| scrollbar color, accepts any hex/color value | +| `cursor` | 'normal' | `string` | cursor for for the scroll bar | +| `disableFadeOut` | false | `boolean` | check if we should hide the scrollbar when user is hovering over | +| `distance` | '1px' | `string[pixel]` | distance in pixels between the side edge and the scrollbar | +| `height` | '250px' | `string[pixel]` | height in pixels of the visible scroll area | +| `horizontal` | false | `boolean` | enable scroll horizontal | +| `opacity` | 0.4 | `number` | sets scrollbar opacity | +| `position` | 'right' | `string` | scrollbar position - left/right | +| `railBorderRadius`| '7px' | `string[pixel]` | sets border radius of the rail | +| `railClass` | 'slimScrollRail' | `string` | defautlt CSS class of the slimscroll rail | +| `railClassH` | 'slimScrollRailHor' | `string` | defautlt CSS class of the slimscroll rail (horizontal) | +| `railColor` | '#333' | `string[pixel]` | sets rail color | +| `railDraggable` | true | `boolean` | whether we should use jQuery UI Draggable to enable bar dragging | +| `railOpacity` | 0.2 | `number` | sets rail opacity | +| `railVisible` | false | `boolean` | sets visibility of the rail | +| `size` | '7px' | `string[pixel]` | width in pixels of the scrollbar and rail | +| `start` | 'top' | `string` | default scroll position on load - top / bottom / $('selector') | +| `touchScrollStep` | 200 | `number` | scroll amount applied when user is using gestures | +| `wheelStep` | 20 | `number` | scroll amount applied to each mouse wheel step | +| `width` | 'auto' | `number|string` | width in pixels of the visible scroll area | +| `wrapperClass` | 'slimScrollDiv' | `string` | defautlt CSS class of the slimscroll wrapper | +| `zIndex` | 90 | `number` | z-index for the scroll bar | + + + +####Example + +``` +$(selector).slimScroll({ + width : '300px', + height : '500px', + size : '10px', + position : 'left', + color : '#ffcc00', + alwaysVisible : true, + distance : '20px', + start : $('#child_image_element'), + railVisible : true, + railColor : '#222', + railOpacity : 0.3, + wheelStep : 10, + allowPageScroll: false, + disableFadeOut : false +}); +``` + + + +###Events + +* `slimscroll` + +When the scrollbar reaches top or bottom of the parent container, slimscroll will trigger the slimscroll event. Use jQuery bind to capture this event: + +``` +$(selector).slimScroll().bind('slimscroll', function(e, pos){ + console.log("Reached " + pos); +}); +``` + +* `slimscrolling` + +When scrolling within slimscroll, the slimscrolling event is triggered. Use jQuery bind to capture this event: + +``` +$(selector).slimScroll().bind('slimscrolling', function(e, msg){ + console.log(msg); +}); +``` + +Note: The slimscrolling event will be triggered no matter if the div has actually been able to move. + + + +###Public Calls + +* `scrollTo` + +Jumps to the specified scroll value. Can be called on any element with slimScroll already enabled. + +``` +$(selector).slimScroll({ + scrollTo: '50px' +}); +``` + +* `scrollBy` + +Increases/decreases current scroll value by specified amount (positive or negative). Can be called on any element with slimScroll already enabled. + +``` +$(selector).slimScroll({ + scrollBy: '60px' +}); +``` + + + + +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. diff --git a/examples/animate-scroll.html b/examples/animate-scroll.html new file mode 100644 index 0000000..9fab418 --- /dev/null +++ b/examples/animate-scroll.html @@ -0,0 +1,54 @@ + + + +jquery.slimscroll - mouse wheel + + + + + + + + + +Fork me on GitHub + +
+
+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam rhoncus, felis interdum condimentum consectetur, nisl libero elementum eros, vehicula congue lacus eros non diam. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus mauris lorem, lacinia id tempus non, imperdiet et leo. Cras sit amet erat sit amet lacus egestas placerat. Aenean ultricies ultrices mauris ac congue. In vel tortor vel velit tristique tempus ac id nisi. Proin quis lorem velit. Nunc dui dui, blandit a ullamcorper vitae, congue fringilla lectus. Aliquam ultricies malesuada feugiat. Vestibulum placerat turpis et eros lobortis vel semper sapien pulvinar.

+

Pellentesque rhoncus aliquet porta. Sed vel magna eu turpis pharetra consequat ut vitae lectus. In molestie sollicitudin mi sit amet convallis. Aliquam erat volutpat. Nullam feugiat placerat ipsum eget malesuada. Nulla facilisis nunc non dolor vehicula pretium. Sed dui magna, sodales id pharetra non, ullamcorper eu sapien. Mauris ac consectetur leo. Mauris consequat, lectus ut bibendum pulvinar, leo magna feugiat enim, eu commodo lacus sem vel ante. Sed tempus metus eget leo mollis vulputate. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.

+

Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed pulvinar rhoncus quam, vel semper tellus viverra id. Nulla rutrum porttitor odio, a rutrum purus gravida non. Etiam ac purus augue, eget vestibulum purus. Aenean venenatis ullamcorper augue, non consequat elit tempor sed. Donec velit sapien, volutpat sed ultricies egestas, semper a ante. Fusce dapibus, quam eget auctor suscipit, nibh leo posuere ante, at auctor nisi lacus in sem. Morbi interdum consectetur euismod. Cras accumsan est lacus. Nulla eleifend, eros vel consequat commodo, arcu nunc malesuada nunc, quis sagittis felis sem ac turpis.

+

Nulla rhoncus elementum convallis. Mauris condimentum aliquet egestas. Ut iaculis nisi eget tellus accumsan venenatis. Maecenas imperdiet aliquam porta. Aenean ultrices dolor sed quam laoreet varius. Curabitur condimentum blandit erat, quis accumsan eros interdum vitae. Curabitur ligula arcu, sollicitudin vitae iaculis sed, blandit sit amet enim. Morbi ullamcorper, metus vel mollis tristique, arcu turpis malesuada nisi, at dignissim lorem odio a orci. Proin ultrices, ipsum ut vestibulum interdum, libero felis auctor mi, vitae convallis nisl justo ac tellus. Integer nec lacinia turpis. Etiam massa nisl, rhoncus quis rutrum in, pretium eu leo. Proin a velit ut nulla laoreet vestibulum. Curabitur eu elit vitae felis auctor tincidunt. Curabitur tincidunt, metus sed sollicitudin cursus, quam elit commodo erat, ut tempor erat sapien vitae velit. Morbi nec viverra erat.

+

Nullam scelerisque facilisis pretium. Vivamus lectus leo, commodo ac sagittis ac, dictum a mi. Donec quis massa ut libero malesuada commodo in et risus. Fusce nunc dolor, aliquet vel rutrum in, molestie sit amet massa. Aliquam suscipit, justo a commodo condimentum, enim sapien fringilla ante, sed lobortis orci lectus in ante. Donec vel interdum est. Donec placerat cursus lacus, eu ultricies nisl tincidunt a. Fusce libero risus, sagittis eleifend iaculis aliquet, condimentum vitae diam. Suspendisse potenti. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Proin leo purus, sodales a venenatis luctus, faucibus ac enim. Sed id metus ac sem lobortis pretium. Mauris faucibus tempor scelerisque. Nunc vulputate interdum tortor, non tincidunt dui condimentum eget. Aenean in porttitor velit. Nam accumsan rhoncus risus id consectetur.

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam rhoncus, felis interdum condimentum consectetur, nisl libero elementum eros, vehicula congue lacus eros non diam. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus mauris lorem, lacinia id tempus non, imperdiet et leo. Cras sit amet erat sit amet lacus egestas placerat. Aenean ultricies ultrices mauris ac congue. In vel tortor vel velit tristique tempus ac id nisi. Proin quis lorem velit. Nunc dui dui, blandit a ullamcorper vitae, congue fringilla lectus. Aliquam ultricies malesuada feugiat. Vestibulum placerat turpis et eros lobortis vel semper sapien pulvinar.

+

Pellentesque rhoncus aliquet porta. Sed vel magna eu turpis pharetra consequat ut vitae lectus. In molestie sollicitudin mi sit amet convallis. Aliquam erat volutpat. Nullam feugiat placerat ipsum eget malesuada. Nulla facilisis nunc non dolor vehicula pretium. Sed dui magna, sodales id pharetra non, ullamcorper eu sapien. Mauris ac consectetur leo. Mauris consequat, lectus ut bibendum pulvinar, leo magna feugiat enim, eu commodo lacus sem vel ante. Sed tempus metus eget leo mollis vulputate. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.

+

Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed pulvinar rhoncus quam, vel semper tellus viverra id. Nulla rutrum porttitor odio, a rutrum purus gravida non. Etiam ac purus augue, eget vestibulum purus. Aenean venenatis ullamcorper augue, non consequat elit tempor sed. Donec velit sapien, volutpat sed ultricies egestas, semper a ante. Fusce dapibus, quam eget auctor suscipit, nibh leo posuere ante, at auctor nisi lacus in sem. Morbi interdum consectetur euismod. Cras accumsan est lacus. Nulla eleifend, eros vel consequat commodo, arcu nunc malesuada nunc, quis sagittis felis sem ac turpis.

+

Nulla rhoncus elementum convallis. Mauris condimentum aliquet egestas. Ut iaculis nisi eget tellus accumsan venenatis. Maecenas imperdiet aliquam porta. Aenean ultrices dolor sed quam laoreet varius. Curabitur condimentum blandit erat, quis accumsan eros interdum vitae. Curabitur ligula arcu, sollicitudin vitae iaculis sed, blandit sit amet enim. Morbi ullamcorper, metus vel mollis tristique, arcu turpis malesuada nisi, at dignissim lorem odio a orci. Proin ultrices, ipsum ut vestibulum interdum, libero felis auctor mi, vitae convallis nisl justo ac tellus. Integer nec lacinia turpis. Etiam massa nisl, rhoncus quis rutrum in, pretium eu leo. Proin a velit ut nulla laoreet vestibulum. Curabitur eu elit vitae felis auctor tincidunt. Curabitur tincidunt, metus sed sollicitudin cursus, quam elit commodo erat, ut tempor erat sapien vitae velit. Morbi nec viverra erat.

+

Nullam scelerisque facilisis pretium. Vivamus lectus leo, commodo ac sagittis ac, dictum a mi. Donec quis massa ut libero malesuada commodo in et risus. Fusce nunc dolor, aliquet vel rutrum in, molestie sit amet massa. Aliquam suscipit, justo a commodo condimentum, enim sapien fringilla ante, sed lobortis orci lectus in ante. Donec vel interdum est. Donec placerat cursus lacus, eu ultricies nisl tincidunt a. Fusce libero risus, sagittis eleifend iaculis aliquet, condimentum vitae diam. Suspendisse potenti. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Proin leo purus, sodales a venenatis luctus, faucibus ac enim. Sed id metus ac sem lobortis pretium. Mauris faucibus tempor scelerisque. Nunc vulputate interdum tortor, non tincidunt dui condimentum eget. Aenean in porttitor velit. Nam accumsan rhoncus risus id consectetur.

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam rhoncus, felis interdum condimentum consectetur, nisl libero elementum eros, vehicula congue lacus eros non diam. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus mauris lorem, lacinia id tempus non, imperdiet et leo. Cras sit amet erat sit amet lacus egestas placerat. Aenean ultricies ultrices mauris ac congue. In vel tortor vel velit tristique tempus ac id nisi. Proin quis lorem velit. Nunc dui dui, blandit a ullamcorper vitae, congue fringilla lectus. Aliquam ultricies malesuada feugiat. Vestibulum placerat turpis et eros lobortis vel semper sapien pulvinar.

+

Pellentesque rhoncus aliquet porta. Sed vel magna eu turpis pharetra consequat ut vitae lectus. In molestie sollicitudin mi sit amet convallis. Aliquam erat volutpat. Nullam feugiat placerat ipsum eget malesuada. Nulla facilisis nunc non dolor vehicula pretium. Sed dui magna, sodales id pharetra non, ullamcorper eu sapien. Mauris ac consectetur leo. Mauris consequat, lectus ut bibendum pulvinar, leo magna feugiat enim, eu commodo lacus sem vel ante. Sed tempus metus eget leo mollis vulputate. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.

+

Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed pulvinar rhoncus quam, vel semper tellus viverra id. Nulla rutrum porttitor odio, a rutrum purus gravida non. Etiam ac purus augue, eget vestibulum purus. Aenean venenatis ullamcorper augue, non consequat elit tempor sed. Donec velit sapien, volutpat sed ultricies egestas, semper a ante. Fusce dapibus, quam eget auctor suscipit, nibh leo posuere ante, at auctor nisi lacus in sem. Morbi interdum consectetur euismod. Cras accumsan est lacus. Nulla eleifend, eros vel consequat commodo, arcu nunc malesuada nunc, quis sagittis felis sem ac turpis.

+

Nulla rhoncus elementum convallis. Mauris condimentum aliquet egestas. Ut iaculis nisi eget tellus accumsan venenatis. Maecenas imperdiet aliquam porta. Aenean ultrices dolor sed quam laoreet varius. Curabitur condimentum blandit erat, quis accumsan eros interdum vitae. Curabitur ligula arcu, sollicitudin vitae iaculis sed, blandit sit amet enim. Morbi ullamcorper, metus vel mollis tristique, arcu turpis malesuada nisi, at dignissim lorem odio a orci. Proin ultrices, ipsum ut vestibulum interdum, libero felis auctor mi, vitae convallis nisl justo ac tellus. Integer nec lacinia turpis. Etiam massa nisl, rhoncus quis rutrum in, pretium eu leo. Proin a velit ut nulla laoreet vestibulum. Curabitur eu elit vitae felis auctor tincidunt. Curabitur tincidunt, metus sed sollicitudin cursus, quam elit commodo erat, ut tempor erat sapien vitae velit. Morbi nec viverra erat.

+

Nullam scelerisque facilisis pretium. Vivamus lectus leo, commodo ac sagittis ac, dictum a mi. Donec quis massa ut libero malesuada commodo in et risus. Fusce nunc dolor, aliquet vel rutrum in, molestie sit amet massa. Aliquam suscipit, justo a commodo condimentum, enim sapien fringilla ante, sed lobortis orci lectus in ante. Donec vel interdum est. Donec placerat cursus lacus, eu ultricies nisl tincidunt a. Fusce libero risus, sagittis eleifend iaculis aliquet, condimentum vitae diam. Suspendisse potenti. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Proin leo purus, sodales a venenatis luctus, faucibus ac enim. Sed id metus ac sem lobortis pretium. Mauris faucibus tempor scelerisque. Nunc vulputate interdum tortor, non tincidunt dui condimentum eget. Aenean in porttitor velit. Nam accumsan rhoncus risus id consectetur.

+
+ +
+  $('#testDiv').slimscroll({
+      animate: true
+  });
+
+ +
+ + + + + \ No newline at end of file diff --git a/examples/navigation.html b/examples/navigation.html index 2df6272..aa2bdbe 100644 --- a/examples/navigation.html +++ b/examples/navigation.html @@ -24,6 +24,7 @@

Facebook-style jQuery Scrollbar

  • wheelStep option
  • nested elements
  • dynamic content
  • +
  • smooth scrolling
  • diff --git a/jquery.slimscroll.js b/jquery.slimscroll.js index 90caed3..bb5edb8 100644 --- a/jquery.slimscroll.js +++ b/jquery.slimscroll.js @@ -1,474 +1,696 @@ -/*! Copyright (c) 2011 Piotr Rochala (http://rocha.la) +/*! + * 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.8 + * Version: 1.3.9 * */ (function($) { + "use strict"; - $.fn.extend({ - slimScroll: function(options) { + $.fn.extend({ + slimScroll: function(options) { - var defaults = { + var defaults = { - // width in pixels of the visible scroll area - width : 'auto', + width : 'auto', // width in pixels of the visible scroll area - // height in pixels of the visible scroll area - height : '250px', + height : '250px', // height in pixels of the visible scroll area - // width in pixels of the scrollbar and rail - size : '7px', + size : '7px', // width in pixels of the scrollbar and rail - // scrollbar color, accepts any hex/color value - color: '#000', + color : '#000', // scrollbar color, accepts any hex/color value - // scrollbar position - left/right - position : 'right', + position : 'right', // scrollbar position - left/right - // distance in pixels between the side edge and the scrollbar - distance : '1px', + distance : '1px', // distance in pixels between the side edge and the scrollbar - // default scroll position on load - top / bottom / $('selector') - start : 'top', + start : 'top', // default scroll position on load - top / bottom / $('selector') - // sets scrollbar opacity - opacity : .4, + opacity : 0.4, // sets scrollbar opacity - // enables always-on mode for the scrollbar - alwaysVisible : false, + alwaysVisible : false, // enables always-on mode for the scrollbar - // check if we should hide the scrollbar when user is hovering over - disableFadeOut : false, + disableFadeOut : false, // check if we should hide the scrollbar when user is hovering over - // sets visibility of the rail - railVisible : false, + railVisible : false, // sets visibility of the rail - // sets rail color - railColor : '#333', + railColor : '#333', // sets rail color - // sets rail opacity - railOpacity : .2, + railOpacity : 0.2, // sets rail opacity - // whether we should use jQuery UI Draggable to enable bar dragging - railDraggable : true, + railDraggable : true, // whether we should use jQuery UI Draggable to enable bar dragging - // defautlt CSS class of the slimscroll rail - railClass : 'slimScrollRail', + horizontal : false, // enable scroll horizontal - // defautlt CSS class of the slimscroll bar - barClass : 'slimScrollBar', + animate : false, // sets animation status on a given scroll - // defautlt CSS class of the slimscroll wrapper - wrapperClass : 'slimScrollDiv', + barFixSize : 0, // fixed bar height/width - // check if mousewheel should scroll the window if we reach top/bottom - allowPageScroll : false, + railClass : 'slimScrollRail', // defautlt CSS class of the slimscroll rail - // scroll amount applied to each mouse wheel step - wheelStep : 20, + barClass : 'slimScrollBar', // defautlt CSS class of the slimscroll bar - // scroll amount applied when user is using gestures - touchScrollStep : 200, + railClassH : 'slimScrollRailHor', // defautlt CSS class of the slimscroll rail (horizontal) - // sets border radius - borderRadius: '7px', + barClassH : 'slimScrollBarHor', // defautlt CSS class of the slimscroll bar (horizontal) - // sets border radius of the rail - railBorderRadius : '7px' - }; + wrapperClass : 'slimScrollDiv', // defautlt CSS class of the slimscroll wrapper - var o = $.extend(defaults, options); + allowPageScroll : false, // check if mousewheel should scroll the window if we reach top/bottom - // do it for every element that matches selector - this.each(function(){ + wheelStep : 20, // scroll amount applied to each mouse wheel step - var isOverPanel, isOverBar, isDragg, queueHide, touchDif, - barHeight, percentScroll, lastScroll, - divS = '
    ', - minBarHeight = 30, - releaseScroll = false; + touchScrollStep : 200, // scroll amount applied when user is using gestures - // used in event handlers and for better minification - var me = $(this); + borderRadius : '7px', // sets border radius - // ensure we are not binding it again - if (me.parent().hasClass(o.wrapperClass)) - { - // start from last bar position - var offset = me.scrollTop(); + railBorderRadius: '7px', // sets border radius of the rail - // find bar and rail - bar = me.siblings('.' + o.barClass); - rail = me.siblings('.' + o.railClass); + cursor : 'normal', // cursor for for the scroll bar - getBarHeight(); + zIndex : 90 // z-index for the scroll bar - // 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); - } else if ('height' in options) { - var h = options.height; - me.parent().css('height', h); - me.css('height', h); - } - - 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(this); + var o = $.extend( defaults, options ); - function _onWheel(e) - { - // use mouse wheel only when mouse is over - if (!isOverPanel) { return; } + // do it for every element that matches selector + this.each( function(){ - var e = e || window.event; + var isOverPanel, isOverBar, isDragg, queueHide, + percentScrollX, percentScrollY, + lastScrollX, lastScrollY, + touchDifX, touchDifY, + barHeight, barWidth, + bar, rail, barH, railH, + divS = '
    ', + minBarHeight = 30, + minBarWidth = 30, + releaseScroll = false; - var delta = 0; - if (e.wheelDelta) { delta = -e.wheelDelta/120; } - if (e.detail) { delta = e.detail / 3; } + // used in event handlers and for better minification + var me = $(this); - var target = e.target || e.srcTarget || e.srcElement; - if ($(target).closest('.' + o.wrapperClass).is(me.parent())) { - // scroll content - scrollContent(delta, true); - } + // ensure we are not binding it again + if ( me.parent().hasClass( o.wrapperClass ) ) + { + // start from last bar position + var offset = me.scrollTop(); - // stop window scroll - if (e.preventDefault && !releaseScroll) { e.preventDefault(); } - if (!releaseScroll) { e.returnValue = false; } - } + // find bar and rail + bar = me.siblings( '.' + o.barClass ); + rail = me.siblings( '.' + o.railClass ); - 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(target) - { - if (window.addEventListener) - { - target.addEventListener('DOMMouseScroll', _onWheel, false ); - target.addEventListener('mousewheel', _onWheel, false ); - } - else - { - document.attachEvent("onmousewheel", _onWheel) - } - } + // only if you need a horizontal scroll (small acceleration) + if ( o.horizontal ) + { + barH = me.siblings( '.' + o.barClassH ); + railH = me.siblings( '.' + o.railClassH ); + } - 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' }); + getBarHeight(); + getBarWidth(); - // hide scrollbar if content is not long enough - var display = barHeight == me.outerHeight() ? 'none' : 'block'; - bar.css({ display: display }); - } + // 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 ); + } + else if ( 'height' in options ) + { + var h = options.height; + me.parent().css( 'height', h ); + me.css( 'height', h ); + } + + 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(); + barH.remove(); + + // only if you need a horizontal scroll (small acceleration) + if ( o.horizontal ) + { + rail.remove(); + railH.remove(); + } + + me.unwrap(); + return; + } + + // scroll content by the given offset + scrollContent( 0, 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; + + var maxLen = o.horizontal ? ( 'calc(100% - ' + o.size ) : '100%'; + + // 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 + rail = $(divS) + .addClass( o.railClass ) + .css({ + width : o.size, + height : maxLen, + position : 'absolute', + top : 0, + display : ( o.alwaysVisible && o.railVisible ) ? 'block' : 'none', + 'border-radius' : o.railBorderRadius, + background : o.railColor, + opacity : o.railOpacity, + zIndex : o.zIndex + }); + + // create scrollbar + bar = $(divS) + .addClass( o.barClass ) + .css({ + cursor : o.cursor, + 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 : o.zIndex + 9 + }); + + // create scrollbar (only if you need a horizontal scroll, small acceleration) + if ( o.horizontal ) + { + // create scrollbar rail + railH = $(divS) + .addClass( o.railClassH ) + .css({ + width : maxLen, + height : o.size, + position : 'absolute', + left : 0, + display : ( o.alwaysVisible && o.railVisible ) ? 'block' : 'none', + 'border-radius' : o.railBorderRadius, + background : o.railColor, + opacity : o.railOpacity, + zIndex : o.zIndex + }); + + // create scrollbar + barH = $(divS) + .addClass( o.barClassH ) + .css({ + cursor : o.cursor, + background : o.color, + height : o.size, + position : 'absolute', + left : 0, + opacity : o.opacity, + display : o.alwaysVisible ? 'block' : 'none', + 'border-radius' : o.borderRadius, + BorderRadius : o.borderRadius, + MozBorderRadius : o.borderRadius, + WebkitBorderRadius : o.borderRadius, + zIndex : o.zIndex + 9 + }); + } + + // 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 ); + + // only if you need a horizontal scroll (small acceleration) + if ( o.horizontal ) + { + // set position + posCss = { bottom: o.distance }; + railH.css( posCss ); + barH.css( posCss ); + // append to parent div + me.parent().append( barH ); + me.parent().append( railH ); + } + + // make it draggable and no longer dependent on the jqueryUI + if ( o.railDraggable ) + { + var $doc = $(document); + + bar.bind( 'mousedown', function(e) { + + isDragg = true; + var t = parseFloat( bar.css('top') ); + var pageY = e.pageY; + + $doc.bind( 'mousemove.slimscroll', function(e){ + bar.css( 'top', t + e.pageY - pageY ); + scrollContent( 0, 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; + + }); + + // only if you need a horizontal scroll (small acceleration) + if ( o.horizontal ) + { + barH.bind( 'mousedown', function(e) { + + isDragg = true; + var t = parseFloat( barH.css('left') ); + var pageX = e.pageX; + + $doc.bind( 'mousemove.slimscroll', function(e){ + barH.css( 'left', t + e.pageX - pageX ); + scrollContent( 0, 0, barH.position().left, 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; + }); + + // only if you need a horizontal scroll (small acceleration) + if ( o.horizontal ) + { + railH.hover( function(){ + showBar(); + }, function(){ + hideBar(); + }); + + barH.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 MSPointerDown', function(e,b){ + if ( e.originalEvent.touches.length ) + { + var touch = e.originalEvent.touches[0]; + // record where touch started + touchDifX = touch.pageX; + touchDifY = touch.pageY; + } + }); + + me.bind( 'touchmove MSPointerMove', function(e){ + // prevent scrolling the page if necessary + if( !releaseScroll ) + { + e.originalEvent.preventDefault(); + } + if ( e.originalEvent.touches.length ) + { + var touch = e.originalEvent.touches[0]; + // see how far user swiped + var diffX = ( touchDifX - touch.pageX ) / o.touchScrollStep; + var diffY = ( touchDifY - touch.pageY ) / o.touchScrollStep; + // scroll content + scrollContent( diffX, diffY, true ); + touchDifX = touch.pageX; + touchDifY = touch.pageY; + } + }); + + // set up initial height + getBarHeight(); + getBarWidth(); + + // check start position + if ( o.start == 'bottom' ) + { + // scroll content to bottom + bar.css({ top: me.outerHeight() - bar.outerHeight() }); + scrollContent( 0, 0, true ); + } + else if ( o.start !== 'top' ) + { + var pos = $(o.start).position(); + + // assume jQuery selector + scrollContent( pos.left, pos.top, null, true ); + + // make sure bar stays hidden + if ( !o.alwaysVisible ) { + bar.hide(); + barH.hide(); + } + } + + // attach scroll events + attachWheel(this); + + + function _onWheel(e) + { + // use mouse wheel only when mouse is over + if ( !isOverPanel ) { return; } + + 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( 0, delta, true ); + } + + // stop window scroll + if ( e.preventDefault && !releaseScroll ) { e.preventDefault(); } + if ( !releaseScroll ) { e.returnValue = false; } + } + + function scrollContent(x, y, isWheel, isJump) + { + releaseScroll = false; + var deltaX = x; + var deltaY = y; + var maxTop = me.outerHeight() - bar.outerHeight() - ( o.horizontal ? o.size : 0 ); + var maxLeft = o.horizontal && ( me.outerWidth() - barH.outerWidth() - o.size ); + + if ( isWheel ) + { + // move bar with mouse wheel + deltaY = parseInt( bar.css('top') ) + y * parseInt( o.wheelStep ) / 100 * bar.outerHeight(); + + // move bar, make sure it doesn't go out + deltaY = Math.min( Math.max( deltaY, 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 + deltaY = ( y > 0 ) ? Math.ceil( deltaY ) : Math.floor( deltaY ); + + // scroll the scrollbar + bar.css({ top: deltaY + 'px' }); + + // only if you need a horizontal scroll (small acceleration) + if ( o.horizontal ) + { + deltaX = parseInt( barH.css('left') ) + x * parseInt( o.wheelStep ) / 100 * barH.outerWidth(); + deltaX = Math.min( Math.max( deltaX, 0 ), maxLeft ); + deltaX = ( x > 0 ) ? Math.ceil( deltaX ) : Math.floor( deltaX ); + barH.css({ left: deltaX + 'px' }); + } + } + + // calculate actual scroll amount + percentScrollY = parseInt( bar.css('top') ) / ( me.outerHeight() - bar.outerHeight() ); + deltaY = percentScrollY * ( me[0].scrollHeight - me.outerHeight() ); + + // calculate actual scroll amount (only if you need a horizontal scroll, small acceleration)) + if ( o.horizontal ) + { + percentScrollX = parseInt( barH.css('left') ) / ( me.outerWidth() - barH.outerWidth() ); + deltaX = percentScrollX * ( me[0].scrollWidth - me.outerWidth() ); + } + + if ( isJump ) + { + deltaY = y; + var offsetTop = deltaY / me[0].scrollHeight * me.outerHeight(); + offsetTopY = Math.min( Math.max( offsetTop, 0 ), maxTop ); + bar.css({ top: offsetTopY + 'px' }); + + // only if you need a horizontal scroll (small acceleration) + if ( o.horizontal ) + { + deltaX = x; + var offsetLeft = deltaX / me[0].scrollWidth * me.outerWidth(); + offsetTopX = Math.min( Math.max( offsetLeft, 0 ), maxLeft ); + barH.css({ left: offsetTopX + 'px' }); + } + } + + // scroll content + if ( o.animate ) + { + // scroll content smoothly using jquery animation + me.stop( true, true ).animate( { scrollTop: deltaY, scrollLeft: deltaX }, 200, 'linear' ); + } + else + { + me.scrollTop( deltaY ); + if ( o.horizontal ) { me.scrollLeft( deltaX ); } + } + + // fire scrolling event + me.trigger( 'slimscrolling', ~~deltaY, o.horizontal && deltaX ); + + // ensure bar is visible + showBar(); + + // trigger hide when scroll is stopped + hideBar(); + } + + function attachWheel(target) + { + if ( window.addEventListener ) + { + target.addEventListener( 'DOMMouseScroll', _onWheel, false ); + target.addEventListener( 'mousewheel', _onWheel, false ); + target.addEventListener( 'MozMousePixelScroll', _onWheel, false ); + } + else + { + document.attachEvent( 'onmousewheel', _onWheel ); + } + } + + function getBarHeight() + { + // calculate scrollbar height and make sure it is not too small + barHeight = o.barFixSize ? parseInt( o.barFixSize ) : 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 getBarWidth() + { + // only if you need a horizontal scroll (small acceleration) + if ( !o.horizontal ) { return; } + + // calculate scrollbar width and make sure it is not too small + barWidth = o.barFixSize ? parseInt( o.barFixSize ) : Math.max( ( me.outerWidth() / me[0].scrollWidth ) * me.outerWidth(), minBarWidth ); + barH.css({ width: barWidth + 'px' }); + + // hide scrollbar if content is not long enough + var display = ~~barWidth == ~~me.outerWidth() ? 'none' : 'block'; + barH.css({ display: display }); + } + + function showBar() + { + // recalculate bar height + getBarHeight(); + getBarWidth(); + clearTimeout(queueHide); + + // when bar reached top or bottom + if ( percentScrollY == ~~percentScrollY || percentScrollX == ~~percentScrollX ) + { + //release wheel + releaseScroll = o.allowPageScroll; + + var msgY, msgX; + + // publish approporiate event + if ( lastScrollY !== percentScrollY ) + { + msgY = ( ~~percentScrollY == 0 ) ? 'top' : 'bottom'; + } + if ( lastScrollX !== percentScrollX ) + { + msgX = ( ~~percentScrollX == 0 ) ? 'left' : 'right'; + } + if ( msgY, msgX ) + { + me.trigger( 'slimscroll', msgY, msgX ); + } + } + else + { + releaseScroll = false; + } + lastScrollY = percentScrollY; + lastScrollX = percentScrollX; + + // show only when required + if( ~~barHeight >= ~~me.outerHeight() ) + { + //allow window scroll + releaseScroll = true; + } + else + { + bar.stop( true, true ).fadeIn( 'fast' ); + if ( o.railVisible ) { rail.stop( true, true ).fadeIn( 'fast' ); } + } + + // only if you need a horizontal scroll (small acceleration) + if( o.horizontal ) + { + if( ~~barWidth >= ~~me.outerWidth() ) + { + //allow window scroll + releaseScroll = true; + } + else + { + barH.stop( true, true ).fadeIn( 'fast' ); + if ( o.railVisible ) { railH.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' ); + + // only if you need a horizontal scroll (small acceleration) + if ( o.horizontal ) + { + barH.fadeOut( 'slow' ); + railH.fadeOut( 'slow' ); + } + } + }, 1000 ); + } + } - 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; } + }); - }); - - // maintain chainability - return this; - } - }); - - $.fn.extend({ - slimscroll: $.fn.slimScroll - }); + $.fn.extend({ + slimscroll: $.fn.slimScroll + }); })(jQuery); diff --git a/jquery.slimscroll.min.js b/jquery.slimscroll.min.js index 7531ab3..900fd26 100644 --- a/jquery.slimscroll.min.js +++ b/jquery.slimscroll.min.js @@ -1,16 +1,9 @@ -/*! Copyright (c) 2011 Piotr Rochala (http://rocha.la) +/*! + * 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.8 + * Version: 1.3.9 * */ -(function(e){e.fn.extend({slimScroll:function(f){var a=e.extend({width:"auto",height:"250px",size:"7px",color:"#000",position:"right",distance:"1px",start:"top",opacity:.4,alwaysVisible:!1,disableFadeOut:!1,railVisible:!1,railColor:"#333",railOpacity:.2,railDraggable:!0,railClass:"slimScrollRail",barClass:"slimScrollBar",wrapperClass:"slimScrollDiv",allowPageScroll:!1,wheelStep:20,touchScrollStep:200,borderRadius:"7px",railBorderRadius:"7px"},f);this.each(function(){function v(d){if(r){d=d||window.event; -var c=0;d.wheelDelta&&(c=-d.wheelDelta/120);d.detail&&(c=d.detail/3);e(d.target||d.srcTarget||d.srcElement).closest("."+a.wrapperClass).is(b.parent())&&n(c,!0);d.preventDefault&&!k&&d.preventDefault();k||(d.returnValue=!1)}}function n(d,g,e){k=!1;var f=b.outerHeight()-c.outerHeight();g&&(g=parseInt(c.css("top"))+d*parseInt(a.wheelStep)/100*c.outerHeight(),g=Math.min(Math.max(g,0),f),g=0=b.outerHeight()?k=!0:(c.stop(!0, -!0).fadeIn("fast"),a.railVisible&&m.stop(!0,!0).fadeIn("fast"))}function p(){a.alwaysVisible||(B=setTimeout(function(){a.disableFadeOut&&r||y||z||(c.fadeOut("slow"),m.fadeOut("slow"))},1E3))}var r,y,z,B,A,u,l,C,k=!1,b=e(this);if(b.parent().hasClass(a.wrapperClass)){var q=b.scrollTop(),c=b.siblings("."+a.barClass),m=b.siblings("."+a.railClass);x();if(e.isPlainObject(f)){if("height"in f&&"auto"==f.height){b.parent().css("height","auto");b.css("height","auto");var h=b.parent().parent().height();b.parent().css("height", -h);b.css("height",h)}else"height"in f&&(h=f.height,b.parent().css("height",h),b.css("height",h));if("scrollTo"in f)q=parseInt(a.scrollTo);else if("scrollBy"in f)q+=parseInt(a.scrollBy);else if("destroy"in f){c.remove();m.remove();b.unwrap();return}n(q,!1,!0)}}else if(!(e.isPlainObject(f)&&"destroy"in f)){a.height="auto"==a.height?b.parent().height():a.height;q=e("
    ").addClass(a.wrapperClass).css({position:"relative",overflow:"hidden",width:a.width,height:a.height});b.css({overflow:"hidden", -width:a.width,height:a.height});var m=e("
    ").addClass(a.railClass).css({width:a.size,height:"100%",position:"absolute",top:0,display:a.alwaysVisible&&a.railVisible?"block":"none","border-radius":a.railBorderRadius,background:a.railColor,opacity:a.railOpacity,zIndex:90}),c=e("
    ").addClass(a.barClass).css({background:a.color,width:a.size,position:"absolute",top:0,opacity:a.opacity,display:a.alwaysVisible?"block":"none","border-radius":a.borderRadius,BorderRadius:a.borderRadius,MozBorderRadius:a.borderRadius, -WebkitBorderRadius:a.borderRadius,zIndex:99}),h="right"==a.position?{right:a.distance}:{left:a.distance};m.css(h);c.css(h);b.wrap(q);b.parent().append(c);b.parent().append(m);a.railDraggable&&c.bind("mousedown",function(a){var b=e(document);z=!0;t=parseFloat(c.css("top"));pageY=a.pageY;b.bind("mousemove.slimscroll",function(a){currTop=t+a.pageY-pageY;c.css("top",currTop);n(0,c.position().top,!1)});b.bind("mouseup.slimscroll",function(a){z=!1;p();b.unbind(".slimscroll")});return!1}).bind("selectstart.slimscroll", -function(a){a.stopPropagation();a.preventDefault();return!1});m.hover(function(){w()},function(){p()});c.hover(function(){y=!0},function(){y=!1});b.hover(function(){r=!0;w();p()},function(){r=!1;p()});b.bind("touchstart",function(a,b){a.originalEvent.touches.length&&(A=a.originalEvent.touches[0].pageY)});b.bind("touchmove",function(b){k||b.originalEvent.preventDefault();b.originalEvent.touches.length&&(n((A-b.originalEvent.touches[0].pageY)/a.touchScrollStep,!0),A=b.originalEvent.touches[0].pageY)}); -x();"bottom"===a.start?(c.css({top:b.outerHeight()-c.outerHeight()}),n(0,!0)):"top"!==a.start&&(n(e(a.start).position().top,null,!0),a.alwaysVisible||c.hide());window.addEventListener?(this.addEventListener("DOMMouseScroll",v,!1),this.addEventListener("mousewheel",v,!1)):document.attachEvent("onmousewheel",v)}});return this}});e.fn.extend({slimscroll:e.fn.slimScroll})})(jQuery); \ No newline at end of file +!function(t){"use strict";t.fn.extend({slimScroll:function(i){var e={width:"auto",height:"250px",size:"7px",color:"#000",position:"right",distance:"1px",start:"top",opacity:.4,alwaysVisible:!1,disableFadeOut:!1,railVisible:!1,railColor:"#333",railOpacity:.2,railDraggable:!0,horizontal:!1,railClass:"slimScrollRail",barClass:"slimScrollBar",railClassH:"slimScrollRailHor",barClassH:"slimScrollBarHor",wrapperClass:"slimScrollDiv",allowPageScroll:!1,wheelStep:20,touchScrollStep:200,borderRadius:"7px",railBorderRadius:"7px"},o=t.extend(e,i);return this.each(function(){function e(i){if(c){i=i||window.event;var e=0;i.wheelDelta&&(e=-i.wheelDelta/120),i.detail&&(e=i.detail/3);var a=i.target||i.srcTarget||i.srcElement;t(a).closest("."+o.wrapperClass).is(B.parent())&&s(0,e,!0),i.preventDefault&&!W&&i.preventDefault(),W||(i.returnValue=!1)}}function s(t,i,e,s){W=!1;var a=t,r=i,l=B.outerHeight()-x.outerHeight()-(o.horizontal?o.size:0),c=o.horizontal&&B.outerWidth()-H.outerWidth()-o.size;if(e&&(r=parseInt(x.css("top"))+i*parseInt(o.wheelStep)/100*x.outerHeight(),r=Math.min(Math.max(r,0),l),r=i>0?Math.ceil(r):Math.floor(r),x.css({top:r+"px"}),o.horizontal&&(a=parseInt(H.css("left"))+t*parseInt(o.wheelStep)/100*H.outerWidth(),a=Math.min(Math.max(a,0),c),a=t>0?Math.ceil(a):Math.floor(a),H.css({left:a+"px"}))),g=parseInt(x.css("top"))/(B.outerHeight()-x.outerHeight()),r=g*(B[0].scrollHeight-B.outerHeight()),o.horizontal&&(f=parseInt(H.css("left"))/(B.outerWidth()-H.outerWidth()),a=f*(B[0].scrollWidth-B.outerWidth())),s){r=i;var d=r/B[0].scrollHeight*B.outerHeight();if(offsetTopY=Math.min(Math.max(d,0),l),x.css({top:offsetTopY+"px"}),o.horizontal){a=t;var u=a/B[0].scrollWidth*B.outerWidth();offsetTopX=Math.min(Math.max(u,0),c),H.css({left:offsetTopX+"px"})}}B.scrollTop(r),o.horizontal&&B.scrollLeft(a),B.trigger("slimscrolling",~~r,o.horizontal&&a),n(),h()}function a(t){window.addEventListener?(t.addEventListener("DOMMouseScroll",e,!1),t.addEventListener("mousewheel",e,!1)):document.attachEvent("onmousewheel",e)}function r(){z=Math.max(B.outerHeight()/B[0].scrollHeight*B.outerHeight(),M),x.css({height:z+"px"});var t=z==B.outerHeight()?"none":"block";x.css({display:t})}function l(){if(o.horizontal){y=Math.max(B.outerWidth()/B[0].scrollWidth*B.outerWidth(),I),H.css({width:y+"px"});var t=~~y==~~B.outerWidth()?"none":"block";H.css({display:t})}}function n(){if(r(),l(),clearTimeout(p),g==~~g||f==~~f){W=o.allowPageScroll;var t,i;v!==g&&(t=0==~~g?"top":"bottom"),b!==f&&(i=0==~~f?"left":"right"),i&&B.trigger("slimscroll",t,i)}else W=!1;v=g,b=f,z>=B.outerHeight()?W=!0:(x.stop(!0,!0).fadeIn("fast"),o.railVisible&&C.stop(!0,!0).fadeIn("fast")),o.horizontal&&(y>=B.outerWidth()?W=!0:(H.stop(!0,!0).fadeIn("fast"),o.railVisible&&R.stop(!0,!0).fadeIn("fast")))}function h(){o.alwaysVisible||(p=setTimeout(function(){o.disableFadeOut&&c||d||u||(x.fadeOut("slow"),C.fadeOut("slow"),o.horizontal&&(H.fadeOut("slow"),R.fadeOut("slow")))},1e3))}var c,d,u,p,f,g,b,v,m,w,z,y,x,C,H,R,S="
    ",M=30,I=30,W=!1,B=t(this);if(B.parent().hasClass(o.wrapperClass)){var V=B.scrollTop();if(x=B.siblings("."+o.barClass),C=B.siblings("."+o.railClass),o.horizontal&&(H=B.siblings("."+o.barClassH),R=B.siblings("."+o.railClassH)),r(),l(),t.isPlainObject(i)){if("height"in i&&"auto"==i.height){B.parent().css("height","auto"),B.css("height","auto");var k=B.parent().parent().height();B.parent().css("height",k),B.css("height",k)}else if("height"in i){var O=i.height;B.parent().css("height",O),B.css("height",O)}if("scrollTo"in i)V=parseInt(o.scrollTo);else if("scrollBy"in i)V+=parseInt(o.scrollBy);else if("destroy"in i)return x.remove(),H.remove(),o.horizontal&&(C.remove(),R.remove()),void B.unwrap();s(0,V,!1,!0)}}else if(!(t.isPlainObject(i)&&"destroy"in i)){o.height="auto"==o.height?B.parent().height():o.height;var D=o.horizontal?"calc(100% - {0}px)".f(o.size):"100%",T=t(S).addClass(o.wrapperClass).css({position:"relative",overflow:"hidden",width:o.width,height:o.height});B.css({overflow:"hidden",width:o.width,height:o.height}),C=t(S).addClass(o.railClass).css({width:o.size,height:D,position:"absolute",top:0,display:o.alwaysVisible&&o.railVisible?"block":"none","border-radius":o.railBorderRadius,background:o.railColor,opacity:o.railOpacity,zIndex:90}),x=t(S).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}),o.horizontal&&(R=t(S).addClass(o.railClassH).css({width:D,height:o.size,position:"absolute",left:0,display:o.alwaysVisible&&o.railVisible?"block":"none","border-radius":o.railBorderRadius,background:o.railColor,opacity:o.railOpacity,zIndex:90}),H=t(S).addClass(o.barClassH).css({background:o.color,height:o.size,position:"absolute",left:0,opacity:o.opacity,display:o.alwaysVisible?"block":"none","border-radius":o.borderRadius,BorderRadius:o.borderRadius,MozBorderRadius:o.borderRadius,WebkitBorderRadius:o.borderRadius,zIndex:99}));var E="right"==o.position?{right:o.distance}:{left:o.distance};if(C.css(E),x.css(E),B.wrap(T),B.parent().append(x),B.parent().append(C),o.horizontal&&(E={bottom:o.distance},R.css(E),H.css(E),B.parent().append(H),B.parent().append(R)),o.railDraggable){var X=t(document);x.bind("mousedown",function(t){u=!0;var i=parseFloat(x.css("top")),e=t.pageY;return X.bind("mousemove.slimscroll",function(t){x.css("top",i+t.pageY-e),s(0,0,x.position().top,!1)}),X.bind("mouseup.slimscroll",function(t){u=!1,h(),X.unbind(".slimscroll")}),!1}).bind("selectstart.slimscroll",function(t){return t.stopPropagation(),t.preventDefault(),!1}),o.horizontal&&H.bind("mousedown",function(t){u=!0;var i=parseFloat(H.css("left")),e=t.pageX;return X.bind("mousemove.slimscroll",function(t){H.css("left",i+t.pageX-e),s(0,0,H.position().left,!1)}),X.bind("mouseup.slimscroll",function(t){u=!1,h(),X.unbind(".slimscroll")}),!1}).bind("selectstart.slimscroll",function(t){return t.stopPropagation(),t.preventDefault(),!1})}if(C.hover(function(){n()},function(){h()}),x.hover(function(){d=!0},function(){d=!1}),o.horizontal&&(R.hover(function(){n()},function(){h()}),H.hover(function(){d=!0},function(){d=!1})),B.hover(function(){c=!0,n(),h()},function(){c=!1,h()}),B.bind("touchstart",function(t,i){if(t.originalEvent.touches.length){var e=t.originalEvent.touches[0];m=e.pageX,w=e.pageY}}),B.bind("touchmove",function(t){if(W||t.originalEvent.preventDefault(),t.originalEvent.touches.length){var i=t.originalEvent.touches[0],e=(m-i.pageX)/o.touchScrollStep,a=(w-i.pageY)/o.touchScrollStep;s(e,a,!0),m=i.pageX,w=i.pageY}}),r(),l(),"bottom"==o.start)x.css({top:B.outerHeight()-x.outerHeight()}),s(0,0,!0);else if("top"!==o.start){var Y=t(o.start).position();s(Y.left,Y.top,null,!0),o.alwaysVisible||(x.hide(),H.hide())}a(this)}}),this}}),t.fn.extend({slimscroll:t.fn.slimScroll})}(jQuery); \ No newline at end of file diff --git a/package.json b/package.json index 147e92d..14310f7 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name" : "jquery-slimscroll", "main" : "jquery.slimscroll.js", - "version" : "1.3.8", + "version" : "1.3.9", "title" : "jQuery slimScroll scrollbar", "description" : "slimScroll is a small jQuery plugin that transforms any div into a scrollable area. slimScroll doesn't occupy any visual space as it only appears on a user initiated mouse-over.", "keywords" : ["scrollbar", "scroll", "slimscroll", "scrollable", "scrolling", "scroller", "ui", "jquery-plugin", "ecosystem:jquery"],