11/*!
2- * perfect-scrollbar v1.2 .0
2+ * perfect-scrollbar v1.3 .0
33 * (c) 2017 Hyunje Jun
44 * @license MIT
55 */
@@ -27,9 +27,10 @@ function div(className) {
2727}
2828
2929var elMatches =
30- Element . prototype . matches ||
31- Element . prototype . webkitMatchesSelector ||
32- Element . prototype . msMatchesSelector ;
30+ typeof Element !== 'undefined' &&
31+ ( Element . prototype . matches ||
32+ Element . prototype . webkitMatchesSelector ||
33+ Element . prototype . msMatchesSelector ) ;
3334
3435function matches ( element , query ) {
3536 if ( ! elMatches ) {
@@ -301,12 +302,18 @@ function outerWidth(element) {
301302}
302303
303304var env = {
304- isWebKit : document && 'WebkitAppearance' in document . documentElement . style ,
305+ isWebKit :
306+ typeof document !== 'undefined' &&
307+ 'WebkitAppearance' in document . documentElement . style ,
305308 supportsTouch :
306- window &&
309+ typeof window !== 'undefined' &&
307310 ( 'ontouchstart' in window ||
308311 ( window . DocumentTouch && document instanceof window . DocumentTouch ) ) ,
309- supportsIePointer : navigator && navigator . msMaxTouchPoints ,
312+ supportsIePointer :
313+ typeof navigator !== 'undefined' && navigator . msMaxTouchPoints ,
314+ isChrome :
315+ typeof navigator !== 'undefined' &&
316+ / C h r o m e / i. test ( navigator && navigator . userAgent ) ,
310317} ;
311318
312319var updateGeometry = function ( i ) {
@@ -709,32 +716,23 @@ var wheel = function(i) {
709716 var element = i . element ;
710717
711718 function shouldPreventDefault ( deltaX , deltaY ) {
712- var scrollTop = element . scrollTop ;
713- if ( deltaX === 0 ) {
714- if ( ! i . scrollbarYActive ) {
715- return false ;
716- }
717- if (
718- ( scrollTop === 0 && deltaY > 0 ) ||
719- ( scrollTop >= i . contentHeight - i . containerHeight && deltaY < 0 )
720- ) {
721- return ! i . settings . wheelPropagation ;
722- }
719+ var isTop = element . scrollTop === 0 ;
720+ var isBottom =
721+ element . scrollTop + element . offsetHeight === element . scrollHeight ;
722+ var isLeft = element . scrollLeft === 0 ;
723+ var isRight =
724+ element . scrollLeft + element . offsetWidth === element . offsetWidth ;
725+
726+ var hitsBound ;
727+
728+ // pick axis with primary direction
729+ if ( Math . abs ( deltaY ) > Math . abs ( deltaX ) ) {
730+ hitsBound = isTop || isBottom ;
731+ } else {
732+ hitsBound = isLeft || isRight ;
723733 }
724734
725- var scrollLeft = element . scrollLeft ;
726- if ( deltaY === 0 ) {
727- if ( ! i . scrollbarXActive ) {
728- return false ;
729- }
730- if (
731- ( scrollLeft === 0 && deltaX < 0 ) ||
732- ( scrollLeft >= i . contentWidth - i . containerWidth && deltaX > 0 )
733- ) {
734- return ! i . settings . wheelPropagation ;
735- }
736- }
737- return true ;
735+ return hitsBound ? ! i . settings . wheelPropagation : true ;
738736 }
739737
740738 function getDeltaFromEvent ( e ) {
@@ -874,7 +872,7 @@ var touch = function(i) {
874872
875873 var element = i . element ;
876874
877- function shouldStopOrPrevent ( deltaX , deltaY ) {
875+ function shouldPrevent ( deltaX , deltaY ) {
878876 var scrollTop = element . scrollTop ;
879877 var scrollLeft = element . scrollLeft ;
880878 var magnitudeX = Math . abs ( deltaX ) ;
@@ -888,10 +886,7 @@ var touch = function(i) {
888886 ( deltaY > 0 && scrollTop === 0 )
889887 ) {
890888 // set prevent for mobile Chrome refresh
891- return {
892- stop : ! i . settings . swipePropagation ,
893- prevent : window . scrollY === 0 ,
894- } ;
889+ return window . scrollY === 0 && deltaY > 0 && env . isChrome ;
895890 }
896891 } else if ( magnitudeX > magnitudeY ) {
897892 // user is perhaps trying to swipe left/right across the page
@@ -900,11 +895,11 @@ var touch = function(i) {
900895 ( deltaX < 0 && scrollLeft === i . contentWidth - i . containerWidth ) ||
901896 ( deltaX > 0 && scrollLeft === 0 )
902897 ) {
903- return { stop : ! i . settings . swipePropagation , prevent : true } ;
898+ return true ;
904899 }
905900 }
906901
907- return { stop : true , prevent : true } ;
902+ return true ;
908903 }
909904
910905 function applyTouchMove ( differenceX , differenceY ) {
@@ -918,15 +913,6 @@ var touch = function(i) {
918913 var startTime = 0 ;
919914 var speed = { } ;
920915 var easingLoop = null ;
921- var inGlobalTouch = false ;
922- var inLocalTouch = false ;
923-
924- function globalTouchStart ( ) {
925- inGlobalTouch = true ;
926- }
927- function globalTouchEnd ( ) {
928- inGlobalTouch = false ;
929- }
930916
931917 function getTouch ( e ) {
932918 if ( e . targetTouches ) {
@@ -959,8 +945,6 @@ var touch = function(i) {
959945 return ;
960946 }
961947
962- inLocalTouch = true ;
963-
964948 var touch = getTouch ( e ) ;
965949
966950 startOffset . pageX = touch . pageX ;
@@ -971,22 +955,66 @@ var touch = function(i) {
971955 if ( easingLoop !== null ) {
972956 clearInterval ( easingLoop ) ;
973957 }
958+ }
974959
975- e . stopPropagation ( ) ;
960+ function shouldBeConsumedByChild ( target , deltaX , deltaY ) {
961+ if ( ! element . contains ( target ) ) {
962+ return false ;
963+ }
964+
965+ var cursor = target ;
966+
967+ while ( cursor && cursor !== element ) {
968+ if ( cursor . classList . contains ( cls . element . consuming ) ) {
969+ return true ;
970+ }
971+
972+ var style = get ( cursor ) ;
973+ var overflow = [ style . overflow , style . overflowX , style . overflowY ] . join (
974+ ''
975+ ) ;
976+
977+ // if scrollable
978+ if ( overflow . match ( / ( s c r o l l | a u t o ) / ) ) {
979+ var maxScrollTop = cursor . scrollHeight - cursor . clientHeight ;
980+ if ( maxScrollTop > 0 ) {
981+ if (
982+ ! ( cursor . scrollTop === 0 && deltaY > 0 ) &&
983+ ! ( cursor . scrollTop === maxScrollTop && deltaY < 0 )
984+ ) {
985+ return true ;
986+ }
987+ }
988+ var maxScrollLeft = cursor . scrollLeft - cursor . clientWidth ;
989+ if ( maxScrollLeft > 0 ) {
990+ if (
991+ ! ( cursor . scrollLeft === 0 && deltaX < 0 ) &&
992+ ! ( cursor . scrollLeft === maxScrollLeft && deltaX > 0 )
993+ ) {
994+ return true ;
995+ }
996+ }
997+ }
998+
999+ cursor = cursor . parentNode ;
1000+ }
1001+
1002+ return false ;
9761003 }
9771004
9781005 function touchMove ( e ) {
979- if ( ! inLocalTouch && i . settings . swipePropagation ) {
980- touchStart ( e ) ;
981- }
982- if ( ! inGlobalTouch && inLocalTouch && shouldHandle ( e ) ) {
1006+ if ( shouldHandle ( e ) ) {
9831007 var touch = getTouch ( e ) ;
9841008
9851009 var currentOffset = { pageX : touch . pageX , pageY : touch . pageY } ;
9861010
9871011 var differenceX = currentOffset . pageX - startOffset . pageX ;
9881012 var differenceY = currentOffset . pageY - startOffset . pageY ;
9891013
1014+ if ( shouldBeConsumedByChild ( e . target , differenceX , differenceY ) ) {
1015+ return ;
1016+ }
1017+
9901018 applyTouchMove ( differenceX , differenceY ) ;
9911019 startOffset = currentOffset ;
9921020
@@ -999,60 +1027,48 @@ var touch = function(i) {
9991027 startTime = currentTime ;
10001028 }
10011029
1002- var ref = shouldStopOrPrevent ( differenceX , differenceY ) ;
1003- var stop = ref . stop ;
1004- var prevent = ref . prevent ;
1005- if ( stop ) { e . stopPropagation ( ) ; }
1006- if ( prevent ) { e . preventDefault ( ) ; }
1030+ if ( shouldPrevent ( differenceX , differenceY ) ) {
1031+ e . preventDefault ( ) ;
1032+ }
10071033 }
10081034 }
10091035 function touchEnd ( ) {
1010- if ( ! inGlobalTouch && inLocalTouch ) {
1011- inLocalTouch = false ;
1012-
1013- if ( i . settings . swipeEasing ) {
1014- clearInterval ( easingLoop ) ;
1015- easingLoop = setInterval ( function ( ) {
1016- if ( i . isInitialized ) {
1017- clearInterval ( easingLoop ) ;
1018- return ;
1019- }
1036+ if ( i . settings . swipeEasing ) {
1037+ clearInterval ( easingLoop ) ;
1038+ easingLoop = setInterval ( function ( ) {
1039+ if ( i . isInitialized ) {
1040+ clearInterval ( easingLoop ) ;
1041+ return ;
1042+ }
10201043
1021- if ( ! speed . x && ! speed . y ) {
1022- clearInterval ( easingLoop ) ;
1023- return ;
1024- }
1044+ if ( ! speed . x && ! speed . y ) {
1045+ clearInterval ( easingLoop ) ;
1046+ return ;
1047+ }
10251048
1026- if ( Math . abs ( speed . x ) < 0.01 && Math . abs ( speed . y ) < 0.01 ) {
1027- clearInterval ( easingLoop ) ;
1028- return ;
1029- }
1049+ if ( Math . abs ( speed . x ) < 0.01 && Math . abs ( speed . y ) < 0.01 ) {
1050+ clearInterval ( easingLoop ) ;
1051+ return ;
1052+ }
10301053
1031- applyTouchMove ( speed . x * 30 , speed . y * 30 ) ;
1054+ applyTouchMove ( speed . x * 30 , speed . y * 30 ) ;
10321055
1033- speed . x *= 0.8 ;
1034- speed . y *= 0.8 ;
1035- } , 10 ) ;
1036- }
1056+ speed . x *= 0.8 ;
1057+ speed . y *= 0.8 ;
1058+ } , 10 ) ;
10371059 }
10381060 }
10391061
10401062 if ( env . supportsTouch ) {
1041- i . event . bind ( window , 'touchstart' , globalTouchStart ) ;
1042- i . event . bind ( window , 'touchend' , globalTouchEnd ) ;
10431063 i . event . bind ( element , 'touchstart' , touchStart ) ;
10441064 i . event . bind ( element , 'touchmove' , touchMove ) ;
10451065 i . event . bind ( element , 'touchend' , touchEnd ) ;
10461066 } else if ( env . supportsIePointer ) {
10471067 if ( window . PointerEvent ) {
1048- i . event . bind ( window , 'pointerdown' , globalTouchStart ) ;
1049- i . event . bind ( window , 'pointerup' , globalTouchEnd ) ;
10501068 i . event . bind ( element , 'pointerdown' , touchStart ) ;
10511069 i . event . bind ( element , 'pointermove' , touchMove ) ;
10521070 i . event . bind ( element , 'pointerup' , touchEnd ) ;
10531071 } else if ( window . MSPointerEvent ) {
1054- i . event . bind ( window , 'MSPointerDown' , globalTouchStart ) ;
1055- i . event . bind ( window , 'MSPointerUp' , globalTouchEnd ) ;
10561072 i . event . bind ( element , 'MSPointerDown' , touchStart ) ;
10571073 i . event . bind ( element , 'MSPointerMove' , touchMove ) ;
10581074 i . event . bind ( element , 'MSPointerUp' , touchEnd ) ;
@@ -1069,7 +1085,6 @@ var defaultSettings = function () { return ({
10691085 scrollYMarginOffset : 0 ,
10701086 suppressScrollX : false ,
10711087 suppressScrollY : false ,
1072- swipePropagation : true ,
10731088 swipeEasing : true ,
10741089 useBothWheelAxes : false ,
10751090 wheelPropagation : false ,
0 commit comments