@@ -12,6 +12,8 @@ angular.module('ngScrollbar', []).directive('ngScrollbar', [
12
12
var mainElm , transculdedContainer , tools , thumb , thumbLine , track ;
13
13
var flags = { bottom : attrs . hasOwnProperty ( 'bottom' ) } ;
14
14
var win = angular . element ( $window ) ;
15
+ var hasAddEventListener = ! ! win [ 0 ] . addEventListener ;
16
+ var hasRemoveEventListener = ! ! win [ 0 ] . removeEventListener ;
15
17
// Elements
16
18
var dragger = { top : 0 } , page = { top : 0 } ;
17
19
// Styles
@@ -55,10 +57,18 @@ angular.module('ngScrollbar', []).directive('ngScrollbar', [
55
57
event . stopPropagation ( ) ;
56
58
} ;
57
59
var wheelHandler = function ( event ) {
58
- var wheelDivider = 20 ;
59
- // so it can be changed easily
60
- var deltaY = event . wheelDeltaY !== undefined ? event . wheelDeltaY / wheelDivider : event . wheelDelta !== undefined ? event . wheelDelta / wheelDivider : - event . detail * ( wheelDivider / 10 ) ;
61
- dragger . top = Math . max ( 0 , Math . min ( parseInt ( page . height , 10 ) - parseInt ( dragger . height , 10 ) , parseInt ( dragger . top , 10 ) - deltaY ) ) ;
60
+ var wheelSpeed = 40 ;
61
+ // Mousewheel speed normalization approach adopted from
62
+ // http://stackoverflow.com/a/13650579/1427418
63
+ var o = event , d = o . detail , w = o . wheelDelta , n = 225 , n1 = n - 1 ;
64
+ // Normalize delta
65
+ d = d ? w && ( f = w / d ) ? d / f : - d / 1.35 : w / 120 ;
66
+ // Quadratic scale if |d| > 1
67
+ d = d < 1 ? d < - 1 ? ( - Math . pow ( d , 2 ) - n1 ) / n : d : ( Math . pow ( d , 2 ) + n1 ) / n ;
68
+ // Delta *should* not be greater than 2...
69
+ event . delta = Math . min ( Math . max ( d / 2 , - 1 ) , 1 ) ;
70
+ event . delta = event . delta * wheelSpeed ;
71
+ dragger . top = Math . max ( 0 , Math . min ( parseInt ( page . height , 10 ) - parseInt ( dragger . height , 10 ) , parseInt ( dragger . top , 10 ) - event . delta ) ) ;
62
72
redraw ( ) ;
63
73
if ( ! ! event . preventDefault ) {
64
74
event . preventDefault ( ) ;
@@ -93,22 +103,31 @@ angular.module('ngScrollbar', []).directive('ngScrollbar', [
93
103
win . off ( 'touchend' , _touchEnd ) ;
94
104
event . stopPropagation ( ) ;
95
105
} ;
96
- var buildScrollbar = function ( rollToBottom ) {
97
- // Getting top position of a parent element to place scroll correctly
98
- var parentOffsetTop = element [ 0 ] . parentElement . offsetTop ;
106
+ var registerEvent = function ( elm ) {
107
+ var wheelEvent = win [ 0 ] . onmousewheel !== undefined ? 'mousewheel' : 'DOMMouseScroll' ;
108
+ if ( hasAddEventListener ) {
109
+ elm . addEventListener ( wheelEvent , wheelHandler , false ) ;
110
+ } else {
111
+ elm . attachEvent ( 'onmousewheel' , wheelHandler ) ;
112
+ }
113
+ } ;
114
+ var removeEvent = function ( elm ) {
99
115
var wheelEvent = win [ 0 ] . onmousewheel !== undefined ? 'mousewheel' : 'DOMMouseScroll' ;
116
+ if ( hasRemoveEventListener ) {
117
+ elm . removeEventListener ( wheelEvent , wheelHandler , false ) ;
118
+ } else {
119
+ elm . detachEvent ( 'onmousewheel' , wheelHandler ) ;
120
+ }
121
+ } ;
122
+ var buildScrollbar = function ( rollToBottom ) {
100
123
rollToBottom = flags . bottom || rollToBottom ;
101
124
mainElm = angular . element ( element . children ( ) [ 0 ] ) ;
102
125
transculdedContainer = angular . element ( mainElm . children ( ) [ 0 ] ) ;
103
126
tools = angular . element ( mainElm . children ( ) [ 1 ] ) ;
104
127
thumb = angular . element ( angular . element ( tools . children ( ) [ 0 ] ) . children ( ) [ 0 ] ) ;
105
128
thumbLine = angular . element ( thumb . children ( ) [ 0 ] ) ;
106
129
track = angular . element ( angular . element ( tools . children ( ) [ 0 ] ) . children ( ) [ 1 ] ) ;
107
- // Check if scroll bar is needed
108
- page . height = element [ 0 ] . offsetHeight - parentOffsetTop ;
109
- if ( page . height < 0 ) {
110
- page . height = element [ 0 ] . offsetHeight ;
111
- }
130
+ page . height = element [ 0 ] . offsetHeight ;
112
131
page . scrollHeight = transculdedContainer [ 0 ] . scrollHeight ;
113
132
if ( page . height < page . scrollHeight ) {
114
133
scope . showYScrollbar = true ;
@@ -125,8 +144,8 @@ angular.module('ngScrollbar', []).directive('ngScrollbar', [
125
144
thumbLine . css ( draggerLineStyle ) ;
126
145
// Bind scroll bar events
127
146
track . bind ( 'click' , trackClick ) ;
128
- // Handl mousewheel
129
- transculdedContainer [ 0 ] . addEventListener ( wheelEvent , wheelHandler , false ) ;
147
+ // Handle mousewheel
148
+ registerEvent ( transculdedContainer [ 0 ] ) ;
130
149
// Drag the scroller with the mouse
131
150
thumb . on ( 'mousedown' , function ( event ) {
132
151
lastOffsetY = event . pageY - thumb [ 0 ] . offsetTop ;
@@ -152,7 +171,7 @@ angular.module('ngScrollbar', []).directive('ngScrollbar', [
152
171
scope . showYScrollbar = false ;
153
172
scope . $emit ( 'scrollbar.hide' ) ;
154
173
thumb . off ( 'mousedown' ) ;
155
- transculdedContainer [ 0 ] . removeEventListener ( wheelEvent , wheelHandler , false ) ;
174
+ removeEvent ( transculdedContainer [ 0 ] ) ;
156
175
transculdedContainer . attr ( 'style' , 'position:relative;top:0' ) ;
157
176
// little hack to remove other inline styles
158
177
mainElm . css ( { height : '100%' } ) ;
0 commit comments