From 87655b0c11c07d13ececa9623b2afca23d2b4323 Mon Sep 17 00:00:00 2001 From: iGureEV <35802704+iGureev@users.noreply.github.com> Date: Mon, 5 Feb 2018 11:12:33 +0300 Subject: [PATCH 01/13] Added horizontal scroll support Added params: horizontal: (default: false) railClassH: barClassH: --- README.md | 5 +- jquery.slimscroll.js | 272 +++++++++++++++++++++++++++++++++------ jquery.slimscroll.min.js | 12 +- package.json | 2 +- 4 files changed, 241 insertions(+), 50 deletions(-) diff --git a/README.md b/README.md index bc90347..b828150 100644 --- a/README.md +++ b/README.md @@ -4,5 +4,6 @@ slimScroll is a small jQuery plugin that transforms any div into a scrollable ar Demo and deocumentation available here: [jQuery slimScroll docs](http://rocha.la/jQuery-slimScroll) -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 +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/jquery.slimscroll.js b/jquery.slimscroll.js index 90caed3..4f6a600 100644 --- a/jquery.slimscroll.js +++ b/jquery.slimscroll.js @@ -2,7 +2,7 @@ * 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($) { @@ -60,6 +60,15 @@ // defautlt CSS class of the slimscroll bar barClass : 'slimScrollBar', + // defautlt CSS class of the slimscroll rail (horizontal) + railClassH : 'slimScrollRailHor', + + // defautlt CSS class of the slimscroll bar (horizontal) + barClassH : 'slimScrollBarHor', + + // enable scroll horizontal + horizontal: false, + // defautlt CSS class of the slimscroll wrapper wrapperClass : 'slimScrollDiv', @@ -84,7 +93,9 @@ // do it for every element that matches selector this.each(function(){ - var isOverPanel, isOverBar, isDragg, queueHide, touchDif, + var isOverPanel, isOverBar, isDragg, queueHide, touchDifX, + touchDifY, barWidth, percentScrollX, percentScrollY, lastScrollX, lastScrollY, barH, railH, + minBarWidth = 30, barHeight, percentScroll, lastScroll, divS = '
', minBarHeight = 30, @@ -103,7 +114,14 @@ bar = me.siblings('.' + o.barClass); rail = me.siblings('.' + o.railClass); + if ( o.horizontal ) + { + barH = me.siblings( '.' + o.barClassH ); + railH = me.siblings( '.' + o.railClassH ); + } + getBarHeight(); + getBarWidth(); // check if we should scroll existing instance if ($.isPlainObject(options)) @@ -136,12 +154,19 @@ // remove slimscroll elements bar.remove(); rail.remove(); + + if ( o.horizontal ) + { + barH.remove(); + railH.remove(); + } + me.unwrap(); return; } // scroll content by the given offset - scrollContent(offset, false, true); + scrollContent( 0, offset, false, true ); } return; @@ -157,6 +182,8 @@ // optionally set height to the parent's height o.height = (o.height == 'auto') ? me.parent().height() : o.height; + var maxLen = o.horizontal ? 'calc(100% - {0}px)'.f( o.size ) : '100%'; + // wrap content var wrapper = $(divS) .addClass(o.wrapperClass) @@ -179,7 +206,7 @@ .addClass(o.railClass) .css({ width: o.size, - height: '100%', + height: maxLen, position: 'absolute', top: 0, display: (o.alwaysVisible && o.railVisible) ? 'block' : 'none', @@ -206,6 +233,38 @@ zIndex: 99 }); + // create scrollbar rail (horizontal) + railH = o.horizontal && $(divS) + .addClass( o.railClassH ) + .css({ + width : maxLen, + height : o.size, + position : 'absolute', + left : 0, + display : ( o.alwaysVisible && o.horizontal && o.railVisible ) ? 'block' : 'none', + 'border-radius' : o.railBorderRadius, + background : o.railColor, + opacity : o.railOpacity, + zIndex : 90 + }); + + // create scrollbar (horizontal) + barH = o.horizontal && $(divS) + .addClass( o.barClassH ) + .css({ + background : o.color, + height : o.size, + position : 'absolute', + left : 0, + opacity : o.opacity, + display : o.alwaysVisible && o.horizontal ? '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); @@ -218,8 +277,21 @@ me.parent().append(bar); me.parent().append(rail); + 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 t, pageY, currTop; + bar.bind("mousedown", function(e) { var $doc = $(document); isDragg = true; @@ -229,7 +301,7 @@ $doc.bind("mousemove.slimscroll", function(e){ currTop = t + e.pageY - pageY; bar.css('top', currTop); - scrollContent(0, bar.position().top, false);// scroll content + scrollContent( 0, 0, bar.position().top, false );// scroll content }); $doc.bind("mouseup.slimscroll", function(e) { @@ -242,6 +314,36 @@ e.preventDefault(); return false; }); + + if ( o.horizontal ) + { + barH.bind( 'mousedown', function(e) { + var $doc = $(document); + + 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 @@ -258,6 +360,20 @@ isOverBar = false; }); + 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; @@ -272,8 +388,10 @@ me.bind('touchstart', function(e,b){ if (e.originalEvent.touches.length) { + var touch = e.originalEvent.touches[0]; // record where touch started - touchDif = e.originalEvent.touches[0].pageY; + touchDifX = touch.pageX; + touchDifY = touch.pageY; } }); @@ -285,42 +403,52 @@ } if (e.originalEvent.touches.length) { + var touch = e.originalEvent.touches[0]; // see how far user swiped - var diff = (touchDif - e.originalEvent.touches[0].pageY) / o.touchScrollStep; + var diffX = ( touchDifX - touch.pageX ) / o.touchScrollStep; + var diffY = ( touchDifY - touch.pageY ) / o.touchScrollStep; // scroll content - scrollContent(diff, true); - touchDif = e.originalEvent.touches[0].pageY; + 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, true); + scrollContent( 0, 0, true ); } else if (o.start !== 'top') { + var pos = $(o.start).position(); + // assume jQuery selector - scrollContent($(o.start).position().top, null, true); + scrollContent( pos.left, pos.top, null, true ); // make sure bar stays hidden - if (!o.alwaysVisible) { bar.hide(); } + 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; } - var e = e || window.event; + e = e || window.event; var delta = 0; if (e.wheelDelta) { delta = -e.wheelDelta/120; } @@ -329,7 +457,7 @@ var target = e.target || e.srcTarget || e.srcElement; if ($(target).closest('.' + o.wrapperClass).is(me.parent())) { // scroll content - scrollContent(delta, true); + scrollContent( 0, delta, true ); } // stop window scroll @@ -337,47 +465,72 @@ if (!releaseScroll) { e.returnValue = false; } } - function scrollContent(y, isWheel, isJump) + function scrollContent(x, y, isWheel, isJump) { releaseScroll = false; - var delta = y; - var maxTop = me.outerHeight() - bar.outerHeight(); + 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 - delta = parseInt(bar.css('top')) + y * parseInt(o.wheelStep) / 100 * bar.outerHeight(); + deltaY = 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); + 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 - delta = (y > 0) ? Math.ceil(delta) : Math.floor(delta); + deltaY = ( y > 0 ) ? Math.ceil( deltaY ) : Math.floor( deltaY ); // scroll the scrollbar - bar.css({ top: delta + 'px' }); + bar.css({ top: deltaY + 'px' }); + + 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 - percentScroll = parseInt(bar.css('top')) / (me.outerHeight() - bar.outerHeight()); - delta = percentScroll * (me[0].scrollHeight - me.outerHeight()); + percentScrollY = parseInt( bar.css('top') ) / ( me.outerHeight() - bar.outerHeight() ); + deltaY = percentScrollY * ( me[0].scrollHeight - me.outerHeight() ); + + // calculate actual scroll amount (horizontal) + if ( o.horizontal ) { + percentScrollX = parseInt( barH.css('left') ) / ( me.outerWidth() - barH.outerWidth() ); + deltaX = percentScrollX * ( me[0].scrollWidth - me.outerWidth() ); + } 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' }); + deltaY = y; + var offsetTop = deltaY / me[0].scrollHeight * me.outerHeight(); + offsetTopY = Math.min( Math.max( offsetTop, 0 ), maxTop ); + bar.css({ top: offsetTopY + 'px' }); + + 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 - me.scrollTop(delta); + me.scrollTop( deltaY ); + if ( o.horizontal ) { me.scrollLeft( deltaX ); } // fire scrolling event - me.trigger('slimscrolling', ~~delta); + me.trigger( 'slimscrolling', ~~deltaY, o.horizontal && deltaX ); // ensure bar is visible showBar(); @@ -410,39 +563,78 @@ bar.css({ display: display }); } + function getBarWidth() + { + if ( !o.horizontal ) { return; } + + // calculate scrollbar height and make sure it is not too small + barWidth = 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 (percentScroll == ~~percentScroll) + if ( percentScrollY == ~~percentScrollY || percentScrollX == ~~percentScrollX ) { //release wheel releaseScroll = o.allowPageScroll; + var msgY, msgX; + // publish approporiate event - if (lastScroll != percentScroll) + if ( lastScrollY !== percentScrollY ) { - var msg = (~~percentScroll == 0) ? 'top' : 'bottom'; - me.trigger('slimscroll', msg); + msgY = ( ~~percentScrollY == 0 ) ? 'top' : 'bottom'; + } + if ( lastScrollX !== percentScrollX ) + { + msgX = ( ~~percentScrollX == 0 ) ? 'left' : 'right'; + } + if ( msgY, msgX ) + { + me.trigger( 'slimscroll', msgY, msgX ); } } else { releaseScroll = false; } - lastScroll = percentScroll; + lastScrollY = percentScrollY; + lastScrollX = percentScrollX; // 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'); } + else + { + bar.stop(true,true).fadeIn('fast'); + if ( o.railVisible ) { rail.stop(true,true).fadeIn('fast'); } + } + 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() @@ -455,6 +647,12 @@ { bar.fadeOut('slow'); rail.fadeOut('slow'); + + if ( o.horizontal ) + { + barH.fadeOut('slow'); + railH.fadeOut('slow'); + } } }, 1000); } diff --git a/jquery.slimscroll.min.js b/jquery.slimscroll.min.js index 7531ab3..e92911f 100644 --- a/jquery.slimscroll.min.js +++ b/jquery.slimscroll.min.js @@ -2,15 +2,7 @@ * 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){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,horizontal:!1,railColor:"#333",railOpacity:.2,railDraggable:!0,railClass:"slimScrollRail",railClassH:"slimScrollRailHor",barClass:"slimScrollBar",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(I.parent())&&s(0,e,!0),i.preventDefault&&!M&&i.preventDefault(),M||(i.returnValue=!1)}}function s(t,i,e,s){M=!1;var a=t,r=i,l=I.outerHeight()-T.outerHeight()-(o.horizontal?o.size:0),c=o.horizontal&&I.outerWidth()-x.outerWidth()-o.size;if(e&&(r=parseInt(T.css("top"))+i*parseInt(o.wheelStep)/100*T.outerHeight(),r=Math.min(Math.max(r,0),l),r=i>0?Math.ceil(r):Math.floor(r),T.css({top:r+"px"}),o.horizontal&&(a=parseInt(x.css("left"))+t*parseInt(o.wheelStep)/100*x.outerWidth(),a=Math.min(Math.max(a,0),c),a=t>0?Math.ceil(a):Math.floor(a),x.css({left:a+"px"}))),w=parseInt(T.css("top"))/(I.outerHeight()-T.outerHeight()),r=w*(I[0].scrollHeight-I.outerHeight()),o.horizontal&&(m=parseInt(x.css("left"))/(I.outerWidth()-x.outerWidth()),a=m*(I[0].scrollWidth-I.outerWidth())),s){r=i;var d=r/I[0].scrollHeight*I.outerHeight();if(offsetTopY=Math.min(Math.max(d,0),l),T.css({top:offsetTopY+"px"}),o.horizontal){a=t;var u=a/I[0].scrollWidth*I.outerWidth();offsetTopX=Math.min(Math.max(u,0),c),x.css({left:offsetTopX+"px"})}}I.scrollTop(r),o.horizontal&&I.scrollLeft(a),I.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(){g=Math.max(I.outerHeight()/I[0].scrollHeight*I.outerHeight(),R),T.css({height:g+"px"});var t=g==I.outerHeight()?"none":"block";T.css({display:t})}function l(){if(o.horizontal){v=Math.max(I.outerWidth()/I[0].scrollWidth*I.outerWidth(),S),x.css({width:v+"px"});var t=~~v==~~I.outerWidth()?"none":"block";x.css({display:t})}}function n(){if(r(),l(),clearTimeout(p),w==~~w||m==~~m){M=o.allowPageScroll;var t,i;y!==w&&(t=0==~~w?"top":"bottom"),z!==m&&(i=0==~~m?"left":"right"),i&&I.trigger("slimscroll",t,i)}else M=!1;y=w,z=m,g>=I.outerHeight()?M=!0:(T.stop(!0,!0).fadeIn("fast"),o.railVisible&&D.stop(!0,!0).fadeIn("fast")),o.horizontal&&(v>=I.outerWidth()?M=!0:(x.stop(!0,!0).fadeIn("fast"),o.railVisible&&C.stop(!0,!0).fadeIn("fast")))}function h(){o.alwaysVisible||(p=setTimeout(function(){o.disableFadeOut&&c||d||u||(T.fadeOut("slow"),D.fadeOut("slow"),o.horizontal&&(x.fadeOut("slow"),C.fadeOut("slow")))},1e3))}var c,d,u,p,f,g,b,v,m,w,z,y,x,C,H="
",R=30,S=30,M=!1,I=t(this);if(I.parent().hasClass(o.wrapperClass)){var W=I.scrollTop();if(T=I.siblings("."+o.barClass),D=I.siblings("."+o.railClass),o.horizontal&&(x=I.siblings("."+o.barClassH),C=I.siblings("."+o.railClassH)),r(),l(),t.isPlainObject(i)){if("height"in i&&"auto"==i.height){I.parent().css("height","auto"),I.css("height","auto");var B=I.parent().parent().height();I.parent().css("height",B),I.css("height",B)}else if("height"in i){var V=i.height;I.parent().css("height",V),I.css("height",V)}if("scrollTo"in i)W=parseInt(o.scrollTo);else if("scrollBy"in i)W+=parseInt(o.scrollBy);else if("destroy"in i)return T.remove(),D.remove(),o.horizontal&&(x.remove(),C.remove()),void I.unwrap();s(0,W,!1,!0)}}else if(!(t.isPlainObject(i)&&"destroy"in i)){o.height="auto"==o.height?I.parent().height():o.height;var k=o.horizontal?"calc(100% - {0}px)".f(o.size):"100%",O=t(H).addClass(o.wrapperClass).css({position:"relative",overflow:"hidden",width:o.width,height:o.height});I.css({overflow:"hidden",width:o.width,height:o.height});var D=t(H).addClass(o.railClass).css({width:o.size,height:k,position:"absolute",top:0,display:o.alwaysVisible&&o.railVisible?"block":"none","border-radius":o.railBorderRadius,background:o.railColor,opacity:o.railOpacity,zIndex:90}),T=t(H).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});C=o.horizontal&&t(H).addClass(o.railClassH).css({width:k,height:o.size,position:"absolute",left:0,display:o.alwaysVisible&&o.horizontal&&o.railVisible?"block":"none","border-radius":o.railBorderRadius,background:o.railColor,opacity:o.railOpacity,zIndex:90}),x=o.horizontal&&t(H).addClass(o.barClassH).css({background:o.color,height:o.size,position:"absolute",left:0,opacity:o.opacity,display:o.alwaysVisible&&o.horizontal?"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(D.css(E),T.css(E),I.wrap(O),I.parent().append(T),I.parent().append(D),o.horizontal&&(E={bottom:o.distance},C.css(E),x.css(E),I.parent().append(x),I.parent().append(C)),o.railDraggable){var X,Y,P;T.bind("mousedown",function(i){var e=t(document);return u=!0,X=parseFloat(T.css("top")),Y=i.pageY,e.bind("mousemove.slimscroll",function(t){P=X+t.pageY-Y,T.css("top",P),s(0,0,T.position().top,!1)}),e.bind("mouseup.slimscroll",function(t){u=!1,h(),e.unbind(".slimscroll")}),!1}).bind("selectstart.slimscroll",function(t){return t.stopPropagation(),t.preventDefault(),!1}),o.horizontal&&x.bind("mousedown",function(i){var e=t(document);u=!0;var o=parseFloat(x.css("left")),a=i.pageX;return e.bind("mousemove.slimscroll",function(t){x.css("left",o+t.pageX-a),s(0,0,x.position().left,!1)}),e.bind("mouseup.slimscroll",function(t){u=!1,h(),e.unbind(".slimscroll")}),!1}).bind("selectstart.slimscroll",function(t){return t.stopPropagation(),t.preventDefault(),!1})}if(D.hover(function(){n()},function(){h()}),T.hover(function(){d=!0},function(){d=!1}),o.horizontal&&(C.hover(function(){n()},function(){h()}),x.hover(function(){d=!0},function(){d=!1})),I.hover(function(){c=!0,n(),h()},function(){c=!1,h()}),I.bind("touchstart",function(t,i){if(t.originalEvent.touches.length){var e=t.originalEvent.touches[0];f=e.pageX,b=e.pageY}}),I.bind("touchmove",function(t){if(M||t.originalEvent.preventDefault(),t.originalEvent.touches.length){var i=t.originalEvent.touches[0],e=(f-i.pageX)/o.touchScrollStep,a=(b-i.pageY)/o.touchScrollStep;s(e,a,!0),f=i.pageX,b=i.pageY}}),r(),l(),"bottom"===o.start)T.css({top:I.outerHeight()-T.outerHeight()}),s(0,0,!0);else if("top"!==o.start){var F=t(o.start).position();s(F.left,F.top,null,!0),o.alwaysVisible||(T.hide(),x.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"], From 08f2647858d2dd6f1e0104fbde82024f7cd74c4b Mon Sep 17 00:00:00 2001 From: iGureEV <35802704+iGureev@users.noreply.github.com> Date: Mon, 5 Feb 2018 11:31:08 +0300 Subject: [PATCH 02/13] Code refactoring --- jquery.slimscroll.js | 1190 +++++++++++++++++++------------------- jquery.slimscroll.min.js | 5 +- 2 files changed, 601 insertions(+), 594 deletions(-) diff --git a/jquery.slimscroll.js b/jquery.slimscroll.js index 4f6a600..4294d91 100644 --- a/jquery.slimscroll.js +++ b/jquery.slimscroll.js @@ -1,4 +1,5 @@ -/*! 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. * @@ -6,667 +7,672 @@ * */ (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', + railClass : 'slimScrollRail', // defautlt CSS class of the slimscroll rail - // defautlt CSS class of the slimscroll rail (horizontal) - railClassH : 'slimScrollRailHor', + barClass : 'slimScrollBar', // defautlt CSS class of the slimscroll bar - // defautlt CSS class of the slimscroll bar (horizontal) - barClassH : 'slimScrollBarHor', + railClassH : 'slimScrollRailHor', // defautlt CSS class of the slimscroll rail (horizontal) - // enable scroll horizontal - horizontal: false, + barClassH : 'slimScrollBarHor', // defautlt CSS class of the slimscroll bar (horizontal) - // defautlt CSS class of the slimscroll wrapper - wrapperClass : 'slimScrollDiv', + wrapperClass : 'slimScrollDiv', // defautlt CSS class of the slimscroll wrapper - // check if mousewheel should scroll the window if we reach top/bottom - allowPageScroll : false, + allowPageScroll : false, // check if mousewheel should scroll the window if we reach top/bottom - // scroll amount applied to each mouse wheel step - wheelStep : 20, + wheelStep : 20, // scroll amount applied to each mouse wheel step - // scroll amount applied when user is using gestures - touchScrollStep : 200, + touchScrollStep : 200, // scroll amount applied when user is using gestures - // sets border radius - borderRadius: '7px', + borderRadius : '7px', // sets border radius - // sets border radius of the rail - railBorderRadius : '7px' - }; + railBorderRadius: '7px' // sets border radius of the rail - var o = $.extend(defaults, options); + }; - // do it for every element that matches selector - this.each(function(){ + var o = $.extend( defaults, options ); - var isOverPanel, isOverBar, isDragg, queueHide, touchDifX, - touchDifY, barWidth, percentScrollX, percentScrollY, lastScrollX, lastScrollY, barH, railH, - minBarWidth = 30, - barHeight, percentScroll, lastScroll, - divS = '
', - minBarHeight = 30, - releaseScroll = false; + // do it for every element that matches selector + this.each( function(){ - // used in event handlers and for better minification - var me = $(this); + var isOverPanel, isOverBar, isDragg, queueHide, + percentScrollX, percentScrollY, + lastScrollX, lastScrollY, + touchDifX, touchDifY, + barHeight, barWidth, + bar, rail, + barH, railH, + divS = '
', + minBarHeight = 30, + minBarWidth = 30, + releaseScroll = false; - // ensure we are not binding it again - if (me.parent().hasClass(o.wrapperClass)) - { - // start from last bar position - var offset = me.scrollTop(); + // used in event handlers and for better minification + var me = $(this); - // find bar and rail - bar = me.siblings('.' + o.barClass); - rail = me.siblings('.' + o.railClass); + // 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.siblings( '.' + o.barClass ); + rail = me.siblings( '.' + o.railClass ); + + // only if you need a horizontal scroll (small acceleration) + if ( o.horizontal ) + { + barH = me.siblings( '.' + o.barClassH ); + railH = me.siblings( '.' + o.railClassH ); + } + + getBarHeight(); + getBarWidth(); + + // 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% - {0}px)'.f( 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 : 90 + }); + + // create scrollbar + 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 + }); + + // 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 : 90 + }); + + // create scrollbar + barH = $(divS) + .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 + }); + } - if ( o.horizontal ) - { - barH = me.siblings( '.' + o.barClassH ); - railH = me.siblings( '.' + o.railClassH ); - } - - getBarHeight(); - getBarWidth(); - - // 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(); + // 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 ) { - barH.remove(); - railH.remove(); + // set position + posCss = { bottom: o.distance }; + railH.css( posCss ); + barH.css( posCss ); + // append to parent div + me.parent().append( barH ); + me.parent().append( railH ); } - me.unwrap(); - return; - } + // make it draggable and no longer dependent on the jqueryUI + if ( o.railDraggable ) + { + var $doc = $(document); - // scroll content by the given offset - scrollContent( 0, offset, false, true ); - } + bar.bind( 'mousedown', function(e) { - return; - } - else if ($.isPlainObject(options)) - { - if ('destroy' in options) - { - return; - } - } + isDragg = true; + var t = parseFloat( bar.css('top') ); + var pageY = e.pageY; - // optionally set height to the parent's height - o.height = (o.height == 'auto') ? me.parent().height() : o.height; - - var maxLen = o.horizontal ? 'calc(100% - {0}px)'.f( 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 - var 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: 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 - }); - - // create scrollbar rail (horizontal) - railH = o.horizontal && $(divS) - .addClass( o.railClassH ) - .css({ - width : maxLen, - height : o.size, - position : 'absolute', - left : 0, - display : ( o.alwaysVisible && o.horizontal && o.railVisible ) ? 'block' : 'none', - 'border-radius' : o.railBorderRadius, - background : o.railColor, - opacity : o.railOpacity, - zIndex : 90 - }); - - // create scrollbar (horizontal) - barH = o.horizontal && $(divS) - .addClass( o.barClassH ) - .css({ - background : o.color, - height : o.size, - position : 'absolute', - left : 0, - opacity : o.opacity, - display : o.alwaysVisible && o.horizontal ? '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); - - 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 ); - } + $doc.bind( 'mousemove.slimscroll', function(e){ + bar.css( 'top', t + e.pageY - pageY ); + scrollContent( 0, 0, bar.position().top, false ); // scroll content + }); - // make it draggable and no longer dependent on the jqueryUI - if (o.railDraggable){ - var t, pageY, currTop; + $doc.bind( 'mouseup.slimscroll', function(e) { + isDragg = false; + hideBar(); + $doc.unbind( '.slimscroll' ); + }); + return false; - bar.bind("mousedown", function(e) { - var $doc = $(document); - isDragg = true; - t = parseFloat(bar.css('top')); - pageY = e.pageY; + }).bind( 'selectstart.slimscroll', function(e){ - $doc.bind("mousemove.slimscroll", function(e){ - currTop = t + e.pageY - pageY; - bar.css('top', currTop); - scrollContent( 0, 0, bar.position().top, false );// scroll content - }); + e.stopPropagation(); + e.preventDefault(); + return false; - $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; - }); - - if ( o.horizontal ) - { - barH.bind( 'mousedown', function(e) { - var $doc = $(document); - - 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; + }); - }); - } - } + // only if you need a horizontal scroll (small acceleration) + if ( o.horizontal ) + { + barH.bind( 'mousedown', function(e) { - // on rail over - rail.hover(function(){ - showBar(); - }, function(){ - hideBar(); - }); - - // on bar over - bar.hover(function(){ - isOverBar = true; - }, function(){ - isOverBar = false; - }); - - if ( o.horizontal ) - { - railH.hover( function(){ - showBar(); - }, function(){ - hideBar(); - }); - barH.hover( function(){ - isOverBar = true; - }, function(){ - isOverBar = false; - }); - } + isDragg = true; + var t = parseFloat( barH.css('left') ); + var pageX = e.pageX; - // 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) - { - var touch = e.originalEvent.touches[0]; - // record where touch started - touchDifX = touch.pageX; - touchDifY = touch.pageY; - } - }); - - me.bind('touchmove', 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(); - } - } + $doc.bind( 'mousemove.slimscroll', function(e){ + barH.css( 'left', t + e.pageX - pageX ); + scrollContent( 0, 0, barH.position().left, false ); // scroll content + }); - // attach scroll events - attachWheel(this); + $doc.bind( 'mouseup.slimscroll', function(e) { + isDragg = false; + hideBar(); + $doc.unbind( '.slimscroll' ); + }); + return false; + }).bind( 'selectstart.slimscroll', function(e){ - function _onWheel(e) - { - // use mouse wheel only when mouse is over - if (!isOverPanel) { return; } + e.stopPropagation(); + e.preventDefault(); + return false; - e = e || window.event; + }); + } + } - var delta = 0; - if (e.wheelDelta) { delta = -e.wheelDelta/120; } - if (e.detail) { delta = e.detail / 3; } + // 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; + }); + } - var target = e.target || e.srcTarget || e.srcElement; - if ($(target).closest('.' + o.wrapperClass).is(me.parent())) { - // scroll content - scrollContent( 0, delta, true ); - } + // 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 ) + { + var touch = e.originalEvent.touches[0]; + // record where touch started + touchDifX = touch.pageX; + touchDifY = touch.pageY; + } + }); + + me.bind( 'touchmove', 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(); - // stop window scroll - if (e.preventDefault && !releaseScroll) { e.preventDefault(); } - if (!releaseScroll) { e.returnValue = false; } - } + // assume jQuery selector + scrollContent( pos.left, pos.top, null, true ); - 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' }); - - 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 (horizontal) - 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' }); - - 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 - 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(); - } + // make sure bar stays hidden + if ( !o.alwaysVisible ) { + bar.hide(); + barH.hide(); + } + } - function attachWheel(target) - { - if (window.addEventListener) - { - target.addEventListener('DOMMouseScroll', _onWheel, false ); - target.addEventListener('mousewheel', _onWheel, false ); - } - else - { - document.attachEvent("onmousewheel", _onWheel) - } - } + // attach scroll events + attachWheel(this); - 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 _onWheel(e) + { + // use mouse wheel only when mouse is over + if ( !isOverPanel ) { return; } - function getBarWidth() - { - if ( !o.horizontal ) { return; } + e = e || window.event; - // calculate scrollbar height and make sure it is not too small - barWidth = Math.max( ( me.outerWidth() / me[0].scrollWidth ) * me.outerWidth(), minBarWidth ); - barH.css({ width: barWidth + 'px' }); + var delta = 0; + if ( e.wheelDelta ) { delta = -e.wheelDelta / 120; } + if ( e.detail ) { delta = e.detail / 3; } - // hide scrollbar if content is not long enough - var display = ~~barWidth == ~~me.outerWidth() ? 'none' : 'block'; - barH.css({ display: display }); - } + var target = e.target || e.srcTarget || e.srcElement; + if ( $(target).closest( '.' + o.wrapperClass ).is( me.parent() ) ) { + // scroll content + scrollContent( 0, delta, true ); + } - 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'); } - } - 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'); } - } - } - } + // stop window scroll + if ( e.preventDefault && !releaseScroll ) { e.preventDefault(); } + if ( !releaseScroll ) { e.returnValue = false; } + } - 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'); + 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 + 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(); + } - if ( o.horizontal ) + function attachWheel(target) { - barH.fadeOut('slow'); - railH.fadeOut('slow'); + if ( window.addEventListener ) + { + target.addEventListener( 'DOMMouseScroll', _onWheel, false ); + target.addEventListener( 'mousewheel', _onWheel, false ); + } + else + { + document.attachEvent( 'onmousewheel', _onWheel ); + } } - } - }, 1000); - } - } - }); + 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 }); + } - // maintain chainability - return this; - } - }); + 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 = 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 ); + } + } + + }); + + // 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 e92911f..900fd26 100644 --- a/jquery.slimscroll.min.js +++ b/jquery.slimscroll.min.js @@ -1,8 +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.9 * */ -!function(t){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,horizontal:!1,railColor:"#333",railOpacity:.2,railDraggable:!0,railClass:"slimScrollRail",railClassH:"slimScrollRailHor",barClass:"slimScrollBar",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(I.parent())&&s(0,e,!0),i.preventDefault&&!M&&i.preventDefault(),M||(i.returnValue=!1)}}function s(t,i,e,s){M=!1;var a=t,r=i,l=I.outerHeight()-T.outerHeight()-(o.horizontal?o.size:0),c=o.horizontal&&I.outerWidth()-x.outerWidth()-o.size;if(e&&(r=parseInt(T.css("top"))+i*parseInt(o.wheelStep)/100*T.outerHeight(),r=Math.min(Math.max(r,0),l),r=i>0?Math.ceil(r):Math.floor(r),T.css({top:r+"px"}),o.horizontal&&(a=parseInt(x.css("left"))+t*parseInt(o.wheelStep)/100*x.outerWidth(),a=Math.min(Math.max(a,0),c),a=t>0?Math.ceil(a):Math.floor(a),x.css({left:a+"px"}))),w=parseInt(T.css("top"))/(I.outerHeight()-T.outerHeight()),r=w*(I[0].scrollHeight-I.outerHeight()),o.horizontal&&(m=parseInt(x.css("left"))/(I.outerWidth()-x.outerWidth()),a=m*(I[0].scrollWidth-I.outerWidth())),s){r=i;var d=r/I[0].scrollHeight*I.outerHeight();if(offsetTopY=Math.min(Math.max(d,0),l),T.css({top:offsetTopY+"px"}),o.horizontal){a=t;var u=a/I[0].scrollWidth*I.outerWidth();offsetTopX=Math.min(Math.max(u,0),c),x.css({left:offsetTopX+"px"})}}I.scrollTop(r),o.horizontal&&I.scrollLeft(a),I.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(){g=Math.max(I.outerHeight()/I[0].scrollHeight*I.outerHeight(),R),T.css({height:g+"px"});var t=g==I.outerHeight()?"none":"block";T.css({display:t})}function l(){if(o.horizontal){v=Math.max(I.outerWidth()/I[0].scrollWidth*I.outerWidth(),S),x.css({width:v+"px"});var t=~~v==~~I.outerWidth()?"none":"block";x.css({display:t})}}function n(){if(r(),l(),clearTimeout(p),w==~~w||m==~~m){M=o.allowPageScroll;var t,i;y!==w&&(t=0==~~w?"top":"bottom"),z!==m&&(i=0==~~m?"left":"right"),i&&I.trigger("slimscroll",t,i)}else M=!1;y=w,z=m,g>=I.outerHeight()?M=!0:(T.stop(!0,!0).fadeIn("fast"),o.railVisible&&D.stop(!0,!0).fadeIn("fast")),o.horizontal&&(v>=I.outerWidth()?M=!0:(x.stop(!0,!0).fadeIn("fast"),o.railVisible&&C.stop(!0,!0).fadeIn("fast")))}function h(){o.alwaysVisible||(p=setTimeout(function(){o.disableFadeOut&&c||d||u||(T.fadeOut("slow"),D.fadeOut("slow"),o.horizontal&&(x.fadeOut("slow"),C.fadeOut("slow")))},1e3))}var c,d,u,p,f,g,b,v,m,w,z,y,x,C,H="
",R=30,S=30,M=!1,I=t(this);if(I.parent().hasClass(o.wrapperClass)){var W=I.scrollTop();if(T=I.siblings("."+o.barClass),D=I.siblings("."+o.railClass),o.horizontal&&(x=I.siblings("."+o.barClassH),C=I.siblings("."+o.railClassH)),r(),l(),t.isPlainObject(i)){if("height"in i&&"auto"==i.height){I.parent().css("height","auto"),I.css("height","auto");var B=I.parent().parent().height();I.parent().css("height",B),I.css("height",B)}else if("height"in i){var V=i.height;I.parent().css("height",V),I.css("height",V)}if("scrollTo"in i)W=parseInt(o.scrollTo);else if("scrollBy"in i)W+=parseInt(o.scrollBy);else if("destroy"in i)return T.remove(),D.remove(),o.horizontal&&(x.remove(),C.remove()),void I.unwrap();s(0,W,!1,!0)}}else if(!(t.isPlainObject(i)&&"destroy"in i)){o.height="auto"==o.height?I.parent().height():o.height;var k=o.horizontal?"calc(100% - {0}px)".f(o.size):"100%",O=t(H).addClass(o.wrapperClass).css({position:"relative",overflow:"hidden",width:o.width,height:o.height});I.css({overflow:"hidden",width:o.width,height:o.height});var D=t(H).addClass(o.railClass).css({width:o.size,height:k,position:"absolute",top:0,display:o.alwaysVisible&&o.railVisible?"block":"none","border-radius":o.railBorderRadius,background:o.railColor,opacity:o.railOpacity,zIndex:90}),T=t(H).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});C=o.horizontal&&t(H).addClass(o.railClassH).css({width:k,height:o.size,position:"absolute",left:0,display:o.alwaysVisible&&o.horizontal&&o.railVisible?"block":"none","border-radius":o.railBorderRadius,background:o.railColor,opacity:o.railOpacity,zIndex:90}),x=o.horizontal&&t(H).addClass(o.barClassH).css({background:o.color,height:o.size,position:"absolute",left:0,opacity:o.opacity,display:o.alwaysVisible&&o.horizontal?"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(D.css(E),T.css(E),I.wrap(O),I.parent().append(T),I.parent().append(D),o.horizontal&&(E={bottom:o.distance},C.css(E),x.css(E),I.parent().append(x),I.parent().append(C)),o.railDraggable){var X,Y,P;T.bind("mousedown",function(i){var e=t(document);return u=!0,X=parseFloat(T.css("top")),Y=i.pageY,e.bind("mousemove.slimscroll",function(t){P=X+t.pageY-Y,T.css("top",P),s(0,0,T.position().top,!1)}),e.bind("mouseup.slimscroll",function(t){u=!1,h(),e.unbind(".slimscroll")}),!1}).bind("selectstart.slimscroll",function(t){return t.stopPropagation(),t.preventDefault(),!1}),o.horizontal&&x.bind("mousedown",function(i){var e=t(document);u=!0;var o=parseFloat(x.css("left")),a=i.pageX;return e.bind("mousemove.slimscroll",function(t){x.css("left",o+t.pageX-a),s(0,0,x.position().left,!1)}),e.bind("mouseup.slimscroll",function(t){u=!1,h(),e.unbind(".slimscroll")}),!1}).bind("selectstart.slimscroll",function(t){return t.stopPropagation(),t.preventDefault(),!1})}if(D.hover(function(){n()},function(){h()}),T.hover(function(){d=!0},function(){d=!1}),o.horizontal&&(C.hover(function(){n()},function(){h()}),x.hover(function(){d=!0},function(){d=!1})),I.hover(function(){c=!0,n(),h()},function(){c=!1,h()}),I.bind("touchstart",function(t,i){if(t.originalEvent.touches.length){var e=t.originalEvent.touches[0];f=e.pageX,b=e.pageY}}),I.bind("touchmove",function(t){if(M||t.originalEvent.preventDefault(),t.originalEvent.touches.length){var i=t.originalEvent.touches[0],e=(f-i.pageX)/o.touchScrollStep,a=(b-i.pageY)/o.touchScrollStep;s(e,a,!0),f=i.pageX,b=i.pageY}}),r(),l(),"bottom"===o.start)T.css({top:I.outerHeight()-T.outerHeight()}),s(0,0,!0);else if("top"!==o.start){var F=t(o.start).position();s(F.left,F.top,null,!0),o.alwaysVisible||(T.hide(),x.hide())}a(this)}}),this}}),t.fn.extend({slimscroll:t.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 From 6f4c023d26936874bed4b670b7026e3d2af6d1d2 Mon Sep 17 00:00:00 2001 From: iGureEV <35802704+iGureev@users.noreply.github.com> Date: Mon, 5 Feb 2018 12:38:43 +0300 Subject: [PATCH 03/13] Add a parseInt to avoid displaying scrollBar for a detected scroll of less than a pixel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Добавлен parseInt, чтобы избежать отображения scrollBar при обнаруженного прокрутки менее пикселя --- jquery.slimscroll.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/jquery.slimscroll.js b/jquery.slimscroll.js index 4294d91..9f35899 100644 --- a/jquery.slimscroll.js +++ b/jquery.slimscroll.js @@ -76,8 +76,7 @@ lastScrollX, lastScrollY, touchDifX, touchDifY, barHeight, barWidth, - bar, rail, - barH, railH, + bar, rail, barH, railH, divS = '
', minBarHeight = 30, minBarWidth = 30, @@ -560,7 +559,7 @@ bar.css({ height: barHeight + 'px' }); // hide scrollbar if content is not long enough - var display = barHeight == me.outerHeight() ? 'none' : 'block'; + var display = ~~barHeight == ~~me.outerHeight() ? 'none' : 'block'; bar.css({ display: display }); } @@ -615,7 +614,7 @@ lastScrollX = percentScrollX; // show only when required - if( barHeight >= me.outerHeight() ) + if( ~~barHeight >= ~~me.outerHeight() ) { //allow window scroll releaseScroll = true; @@ -629,7 +628,7 @@ // only if you need a horizontal scroll (small acceleration) if( o.horizontal ) { - if( barWidth >= me.outerWidth() ) + if( ~~barWidth >= ~~me.outerWidth() ) { //allow window scroll releaseScroll = true; From 31aa19feac34a503a47eef6913c3528b73c5a4de Mon Sep 17 00:00:00 2001 From: iGureEV <35802704+iGureev@users.noreply.github.com> Date: Mon, 5 Feb 2018 12:44:38 +0300 Subject: [PATCH 04/13] Add smooth scrolling support via jQuery animation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Добавлена поддержка плавной прокрутки через анимацию jQuery --- examples/animate-scroll.html | 54 ++++++++++++++++++++++++++++++++++++ examples/navigation.html | 1 + jquery.slimscroll.js | 14 ++++++++-- 3 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 examples/animate-scroll.html 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 9f35899..893f981 100644 --- a/jquery.slimscroll.js +++ b/jquery.slimscroll.js @@ -44,6 +44,8 @@ horizontal : false, // enable scroll horizontal + animate : false, // sets animation status on a given scroll + railClass : 'slimScrollRail', // defautlt CSS class of the slimscroll rail barClass : 'slimScrollBar', // defautlt CSS class of the slimscroll bar @@ -526,8 +528,16 @@ } // scroll content - me.scrollTop( deltaY ); - if ( o.horizontal ) { me.scrollLeft( deltaX ); } + 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 ); From de9fd8ec33dcb0cef4ef383226907034ca15881f Mon Sep 17 00:00:00 2001 From: iGureEV <35802704+iGureev@users.noreply.github.com> Date: Mon, 5 Feb 2018 12:58:45 +0300 Subject: [PATCH 05/13] small fix: removed dependency --- jquery.slimscroll.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jquery.slimscroll.js b/jquery.slimscroll.js index 893f981..f0b9c1d 100644 --- a/jquery.slimscroll.js +++ b/jquery.slimscroll.js @@ -170,7 +170,7 @@ // optionally set height to the parent's height o.height = ( o.height == 'auto' ) ? me.parent().height() : o.height; - var maxLen = o.horizontal ? 'calc(100% - {0}px)'.f( o.size ) : '100%'; + var maxLen = o.horizontal ? ( 'calc(100% - ' + o.size ) : '100%'; // wrap content var wrapper = $(divS) From d4878af08c72152517086493b9220fb2da2d9365 Mon Sep 17 00:00:00 2001 From: iGureEV <35802704+iGureev@users.noreply.github.com> Date: Mon, 5 Feb 2018 13:29:51 +0300 Subject: [PATCH 06/13] Adding the ability to set a z-index for the scroll bar --- jquery.slimscroll.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/jquery.slimscroll.js b/jquery.slimscroll.js index f0b9c1d..4b831c8 100644 --- a/jquery.slimscroll.js +++ b/jquery.slimscroll.js @@ -64,7 +64,9 @@ borderRadius : '7px', // sets border radius - railBorderRadius: '7px' // sets border radius of the rail + railBorderRadius: '7px', // sets border radius of the rail + + zIndex : 90 // z-index for the scroll bar }; @@ -201,7 +203,7 @@ 'border-radius' : o.railBorderRadius, background : o.railColor, opacity : o.railOpacity, - zIndex : 90 + zIndex : zIndex }); // create scrollbar @@ -218,7 +220,7 @@ BorderRadius : o.borderRadius, MozBorderRadius : o.borderRadius, WebkitBorderRadius : o.borderRadius, - zIndex : 99 + zIndex : zIndex + 9 }); // create scrollbar (only if you need a horizontal scroll, small acceleration) @@ -236,7 +238,7 @@ 'border-radius' : o.railBorderRadius, background : o.railColor, opacity : o.railOpacity, - zIndex : 90 + zIndex : zIndex }); // create scrollbar @@ -253,7 +255,7 @@ BorderRadius : o.borderRadius, MozBorderRadius : o.borderRadius, WebkitBorderRadius : o.borderRadius, - zIndex : 99 + zIndex : zIndex + 9 }); } From deaa5a8e03586d90e5b60324cf9eda814c8d7e07 Mon Sep 17 00:00:00 2001 From: iGureEV <35802704+iGureev@users.noreply.github.com> Date: Mon, 5 Feb 2018 13:36:13 +0300 Subject: [PATCH 07/13] Adding the ability to set a cursor for the scroll bar --- jquery.slimscroll.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/jquery.slimscroll.js b/jquery.slimscroll.js index 4b831c8..6d67d78 100644 --- a/jquery.slimscroll.js +++ b/jquery.slimscroll.js @@ -66,6 +66,8 @@ railBorderRadius: '7px', // sets border radius of the rail + cursor : null, // cursor for for the scroll bar + zIndex : 90 // z-index for the scroll bar }; @@ -210,6 +212,7 @@ bar = $(divS) .addClass( o.barClass ) .css({ + cursor : o.cursor, background : o.color, width : o.size, position : 'absolute', @@ -245,6 +248,7 @@ barH = $(divS) .addClass( o.barClassH ) .css({ + cursor : o.cursor, background : o.color, height : o.size, position : 'absolute', From bf3f8c2818074f5fb179209fab65bbc743042801 Mon Sep 17 00:00:00 2001 From: iGureEV <35802704+iGureev@users.noreply.github.com> Date: Mon, 5 Feb 2018 13:36:40 +0300 Subject: [PATCH 08/13] code refactoring --- jquery.slimscroll.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/jquery.slimscroll.js b/jquery.slimscroll.js index 6d67d78..32bca63 100644 --- a/jquery.slimscroll.js +++ b/jquery.slimscroll.js @@ -205,7 +205,7 @@ 'border-radius' : o.railBorderRadius, background : o.railColor, opacity : o.railOpacity, - zIndex : zIndex + zIndex : o.zIndex }); // create scrollbar @@ -223,7 +223,7 @@ BorderRadius : o.borderRadius, MozBorderRadius : o.borderRadius, WebkitBorderRadius : o.borderRadius, - zIndex : zIndex + 9 + zIndex : o.zIndex + 9 }); // create scrollbar (only if you need a horizontal scroll, small acceleration) @@ -236,12 +236,12 @@ width : maxLen, height : o.size, position : 'absolute', - left : 0, + left : 0, display : ( o.alwaysVisible && o.railVisible ) ? 'block' : 'none', 'border-radius' : o.railBorderRadius, background : o.railColor, opacity : o.railOpacity, - zIndex : zIndex + zIndex : o.zIndex }); // create scrollbar @@ -252,14 +252,14 @@ background : o.color, height : o.size, position : 'absolute', - left : 0, + left : 0, opacity : o.opacity, display : o.alwaysVisible ? 'block' : 'none', 'border-radius' : o.borderRadius, BorderRadius : o.borderRadius, MozBorderRadius : o.borderRadius, WebkitBorderRadius : o.borderRadius, - zIndex : zIndex + 9 + zIndex : o.zIndex + 9 }); } @@ -404,8 +404,8 @@ // prevent scrolling the page if necessary if( !releaseScroll ) { - e.originalEvent.preventDefault(); - } + e.originalEvent.preventDefault(); + } if ( e.originalEvent.touches.length ) { var touch = e.originalEvent.touches[0]; From 300c7acb79ef6667523f38a0f3eedbe40111b8be Mon Sep 17 00:00:00 2001 From: iGureEV <35802704+iGureev@users.noreply.github.com> Date: Mon, 5 Feb 2018 14:47:22 +0300 Subject: [PATCH 09/13] readme --- README.md | 124 +++++++++++++++++++++++++++++++++++++++++++ jquery.slimscroll.js | 2 +- 2 files changed, 125 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b828150..3aa6bc8 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,132 @@ 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. +##Documentation + Demo and deocumentation 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) | +| `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/jquery.slimscroll.js b/jquery.slimscroll.js index 32bca63..ed82da5 100644 --- a/jquery.slimscroll.js +++ b/jquery.slimscroll.js @@ -66,7 +66,7 @@ railBorderRadius: '7px', // sets border radius of the rail - cursor : null, // cursor for for the scroll bar + cursor : 'normal', // cursor for for the scroll bar zIndex : 90 // z-index for the scroll bar From 331aace9861267f3a2a7141837a45bfbe05f9963 Mon Sep 17 00:00:00 2001 From: iGureEV <35802704+iGureev@users.noreply.github.com> Date: Mon, 5 Feb 2018 15:10:32 +0300 Subject: [PATCH 10/13] Setting a fixed bar height --- README.md | 61 ++++++++++++++++++++++---------------------- jquery.slimscroll.js | 6 +++-- 2 files changed, 35 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index 3aa6bc8..c77bab8 100644 --- a/README.md +++ b/README.md @@ -21,36 +21,37 @@ $('document').ready(function(){ ###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) | -| `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 | +| 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 | diff --git a/jquery.slimscroll.js b/jquery.slimscroll.js index ed82da5..4570883 100644 --- a/jquery.slimscroll.js +++ b/jquery.slimscroll.js @@ -46,6 +46,8 @@ animate : false, // sets animation status on a given scroll + barFixSize : 0, // fixed bar height/width + railClass : 'slimScrollRail', // defautlt CSS class of the slimscroll rail barClass : 'slimScrollBar', // defautlt CSS class of the slimscroll bar @@ -571,7 +573,7 @@ function getBarHeight() { // calculate scrollbar height and make sure it is not too small - barHeight = Math.max( ( me.outerHeight() / me[0].scrollHeight ) * me.outerHeight(), minBarHeight ); + 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 @@ -585,7 +587,7 @@ if ( !o.horizontal ) { return; } // calculate scrollbar width and make sure it is not too small - barWidth = Math.max( ( me.outerWidth() / me[0].scrollWidth ) * me.outerWidth(), minBarWidth ); + 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 From 66eda94ad2ad48dd167ebbaf48208fae4b5e79ee Mon Sep 17 00:00:00 2001 From: iGureEV <35802704+iGureev@users.noreply.github.com> Date: Mon, 5 Feb 2018 15:38:19 +0300 Subject: [PATCH 11/13] Fix typo in README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c77bab8..f40a6a9 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ slimScroll is a small jQuery plugin that transforms any div into a scrollable ar ##Documentation -Demo and deocumentation available here: [jQuery slimScroll docs](http://rocha.la/jQuery-slimScroll) +Demo and documentation available here: [jQuery slimScroll docs](http://rocha.la/jQuery-slimScroll) ###Example ``` From 67aec951d0545027115da6e780de0d0efafe6103 Mon Sep 17 00:00:00 2001 From: iGureEV <35802704+iGureev@users.noreply.github.com> Date: Mon, 5 Feb 2018 15:42:06 +0300 Subject: [PATCH 12/13] Fixes issues with Firefox (jumpy scrolling) --- jquery.slimscroll.js | 1 + 1 file changed, 1 insertion(+) diff --git a/jquery.slimscroll.js b/jquery.slimscroll.js index 4570883..238ea08 100644 --- a/jquery.slimscroll.js +++ b/jquery.slimscroll.js @@ -563,6 +563,7 @@ { target.addEventListener( 'DOMMouseScroll', _onWheel, false ); target.addEventListener( 'mousewheel', _onWheel, false ); + target.addEventListener( 'MozMousePixelScroll', _onWheel, false ); } else { From 7c692ee920e4ef373750ee18f85589a22ffbd50c Mon Sep 17 00:00:00 2001 From: iGureEV <35802704+iGureev@users.noreply.github.com> Date: Mon, 5 Feb 2018 15:42:57 +0300 Subject: [PATCH 13/13] Enables scrolling in IE10 and IE11 --- jquery.slimscroll.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jquery.slimscroll.js b/jquery.slimscroll.js index 238ea08..bb5edb8 100644 --- a/jquery.slimscroll.js +++ b/jquery.slimscroll.js @@ -392,7 +392,7 @@ }); // support for mobile - me.bind( 'touchstart', function(e,b){ + me.bind( 'touchstart MSPointerDown', function(e,b){ if ( e.originalEvent.touches.length ) { var touch = e.originalEvent.touches[0]; @@ -402,7 +402,7 @@ } }); - me.bind( 'touchmove', function(e){ + me.bind( 'touchmove MSPointerMove', function(e){ // prevent scrolling the page if necessary if( !releaseScroll ) {