1
1
/*!
2
- * perfect-scrollbar v1.2 .0
2
+ * perfect-scrollbar v1.3 .0
3
3
* (c) 2017 Hyunje Jun
4
4
* @license MIT
5
5
*/
@@ -27,9 +27,10 @@ function div(className) {
27
27
}
28
28
29
29
var 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 ) ;
33
34
34
35
function matches ( element , query ) {
35
36
if ( ! elMatches ) {
@@ -301,12 +302,18 @@ function outerWidth(element) {
301
302
}
302
303
303
304
var env = {
304
- isWebKit : document && 'WebkitAppearance' in document . documentElement . style ,
305
+ isWebKit :
306
+ typeof document !== 'undefined' &&
307
+ 'WebkitAppearance' in document . documentElement . style ,
305
308
supportsTouch :
306
- window &&
309
+ typeof window !== 'undefined' &&
307
310
( 'ontouchstart' in window ||
308
311
( 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 ) ,
310
317
} ;
311
318
312
319
var updateGeometry = function ( i ) {
@@ -709,32 +716,23 @@ var wheel = function(i) {
709
716
var element = i . element ;
710
717
711
718
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 ;
723
733
}
724
734
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 ;
738
736
}
739
737
740
738
function getDeltaFromEvent ( e ) {
@@ -874,7 +872,7 @@ var touch = function(i) {
874
872
875
873
var element = i . element ;
876
874
877
- function shouldStopOrPrevent ( deltaX , deltaY ) {
875
+ function shouldPrevent ( deltaX , deltaY ) {
878
876
var scrollTop = element . scrollTop ;
879
877
var scrollLeft = element . scrollLeft ;
880
878
var magnitudeX = Math . abs ( deltaX ) ;
@@ -888,10 +886,7 @@ var touch = function(i) {
888
886
( deltaY > 0 && scrollTop === 0 )
889
887
) {
890
888
// 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 ;
895
890
}
896
891
} else if ( magnitudeX > magnitudeY ) {
897
892
// user is perhaps trying to swipe left/right across the page
@@ -900,11 +895,11 @@ var touch = function(i) {
900
895
( deltaX < 0 && scrollLeft === i . contentWidth - i . containerWidth ) ||
901
896
( deltaX > 0 && scrollLeft === 0 )
902
897
) {
903
- return { stop : ! i . settings . swipePropagation , prevent : true } ;
898
+ return true ;
904
899
}
905
900
}
906
901
907
- return { stop : true , prevent : true } ;
902
+ return true ;
908
903
}
909
904
910
905
function applyTouchMove ( differenceX , differenceY ) {
@@ -918,15 +913,6 @@ var touch = function(i) {
918
913
var startTime = 0 ;
919
914
var speed = { } ;
920
915
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
- }
930
916
931
917
function getTouch ( e ) {
932
918
if ( e . targetTouches ) {
@@ -959,8 +945,6 @@ var touch = function(i) {
959
945
return ;
960
946
}
961
947
962
- inLocalTouch = true ;
963
-
964
948
var touch = getTouch ( e ) ;
965
949
966
950
startOffset . pageX = touch . pageX ;
@@ -971,22 +955,66 @@ var touch = function(i) {
971
955
if ( easingLoop !== null ) {
972
956
clearInterval ( easingLoop ) ;
973
957
}
958
+ }
974
959
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 ;
976
1003
}
977
1004
978
1005
function touchMove ( e ) {
979
- if ( ! inLocalTouch && i . settings . swipePropagation ) {
980
- touchStart ( e ) ;
981
- }
982
- if ( ! inGlobalTouch && inLocalTouch && shouldHandle ( e ) ) {
1006
+ if ( shouldHandle ( e ) ) {
983
1007
var touch = getTouch ( e ) ;
984
1008
985
1009
var currentOffset = { pageX : touch . pageX , pageY : touch . pageY } ;
986
1010
987
1011
var differenceX = currentOffset . pageX - startOffset . pageX ;
988
1012
var differenceY = currentOffset . pageY - startOffset . pageY ;
989
1013
1014
+ if ( shouldBeConsumedByChild ( e . target , differenceX , differenceY ) ) {
1015
+ return ;
1016
+ }
1017
+
990
1018
applyTouchMove ( differenceX , differenceY ) ;
991
1019
startOffset = currentOffset ;
992
1020
@@ -999,60 +1027,48 @@ var touch = function(i) {
999
1027
startTime = currentTime ;
1000
1028
}
1001
1029
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
+ }
1007
1033
}
1008
1034
}
1009
1035
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
+ }
1020
1043
1021
- if ( ! speed . x && ! speed . y ) {
1022
- clearInterval ( easingLoop ) ;
1023
- return ;
1024
- }
1044
+ if ( ! speed . x && ! speed . y ) {
1045
+ clearInterval ( easingLoop ) ;
1046
+ return ;
1047
+ }
1025
1048
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
+ }
1030
1053
1031
- applyTouchMove ( speed . x * 30 , speed . y * 30 ) ;
1054
+ applyTouchMove ( speed . x * 30 , speed . y * 30 ) ;
1032
1055
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 ) ;
1037
1059
}
1038
1060
}
1039
1061
1040
1062
if ( env . supportsTouch ) {
1041
- i . event . bind ( window , 'touchstart' , globalTouchStart ) ;
1042
- i . event . bind ( window , 'touchend' , globalTouchEnd ) ;
1043
1063
i . event . bind ( element , 'touchstart' , touchStart ) ;
1044
1064
i . event . bind ( element , 'touchmove' , touchMove ) ;
1045
1065
i . event . bind ( element , 'touchend' , touchEnd ) ;
1046
1066
} else if ( env . supportsIePointer ) {
1047
1067
if ( window . PointerEvent ) {
1048
- i . event . bind ( window , 'pointerdown' , globalTouchStart ) ;
1049
- i . event . bind ( window , 'pointerup' , globalTouchEnd ) ;
1050
1068
i . event . bind ( element , 'pointerdown' , touchStart ) ;
1051
1069
i . event . bind ( element , 'pointermove' , touchMove ) ;
1052
1070
i . event . bind ( element , 'pointerup' , touchEnd ) ;
1053
1071
} else if ( window . MSPointerEvent ) {
1054
- i . event . bind ( window , 'MSPointerDown' , globalTouchStart ) ;
1055
- i . event . bind ( window , 'MSPointerUp' , globalTouchEnd ) ;
1056
1072
i . event . bind ( element , 'MSPointerDown' , touchStart ) ;
1057
1073
i . event . bind ( element , 'MSPointerMove' , touchMove ) ;
1058
1074
i . event . bind ( element , 'MSPointerUp' , touchEnd ) ;
@@ -1069,7 +1085,6 @@ var defaultSettings = function () { return ({
1069
1085
scrollYMarginOffset : 0 ,
1070
1086
suppressScrollX : false ,
1071
1087
suppressScrollY : false ,
1072
- swipePropagation : true ,
1073
1088
swipeEasing : true ,
1074
1089
useBothWheelAxes : false ,
1075
1090
wheelPropagation : false ,
0 commit comments