@@ -47,6 +47,11 @@ function getScrolledToTopChanged(currentTop, lastTop, offset) {
47
47
return { isAtTop, isAtTopChanged } ;
48
48
}
49
49
50
+ function captureClick ( e ) {
51
+ e . stopPropagation ( ) ;
52
+ window . removeEventListener ( 'click' , captureClick , true ) ;
53
+ }
54
+
50
55
class ScrollView extends Component {
51
56
// @argument (optional('number'))
52
57
// contentHeight; // optional, when not provided, we measure the size
@@ -155,18 +160,20 @@ class ScrollView extends Component {
155
160
) ;
156
161
}
157
162
158
- onScrollChange ( left , top ) {
163
+ onScrollChange ( _left , top ) {
159
164
let scrollTop = top | 0 ;
160
165
if ( this . isDestroyed || this . isDestroying ) {
161
166
return ;
162
167
}
163
168
let { scroller } = this ;
169
+ let isScrolling = ! ! ( scroller . __isDragging || scroller . __isDecelerating || scroller . __isAnimating ) ;
170
+ this . _isScrolling = isScrolling ;
164
171
this . _decelerationVelocityY = scroller . __decelerationVelocityY ;
165
172
this . applyScrollTop ( {
166
173
scrollTop,
167
174
lastTop : this . _appliedScrollTop ,
168
- isScrolling : ! ! ( scroller . __isDragging || scroller . __isDecelerating || scroller . __isAnimating ) ,
169
- decelerationVelocityY : this . _decelerationVelocityY
175
+ isScrolling,
176
+ decelerationVelocityY : this . _decelerationVelocityY
170
177
} ) ;
171
178
if ( + ( new Date ( ) ) - this . _lastMeasurement > MEASUREMENT_INTERVAL_WHILE_SCROLLING_OR_OFFSCREEN ) {
172
179
this . measureClientAndContent ( ) ;
@@ -242,25 +249,28 @@ class ScrollView extends Component {
242
249
}
243
250
244
251
doTouchStart ( touches , timeStamp ) {
252
+ this . _wasScrollingAtTouchStart = this . _isScrolling ;
245
253
this . scroller . doTouchStart ( touches , timeStamp ) ;
246
254
}
247
255
248
256
doTouchMove ( touches , timeStamp , scale ) {
249
257
this . scroller . doTouchMove ( touches , timeStamp , scale )
250
258
}
251
259
252
- doTouchEnd ( touches , timeStamp , event ) {
260
+ doTouchEnd ( _touches , timeStamp , event ) {
253
261
let preventClick = this . needsPreventClick ( )
254
-
262
+
255
263
if ( preventClick ) {
256
- event . preventDefault ( ) ;
264
+ // A touchend event can prevent a follow-on click event by calling preventDefault.
265
+ // However, a mouseup event cannot do this so we need to capture the upcoming click instead.
266
+ if ( event instanceof MouseEvent ) {
267
+ window . addEventListener ( 'click' , captureClick , true ) ;
268
+ } else {
269
+ event . preventDefault ( ) ;
270
+ }
257
271
}
258
272
259
273
this . scroller . doTouchEnd ( timeStamp ) ;
260
-
261
- if ( preventClick ) {
262
- this . _decelerationVelocityY = null ;
263
- }
264
274
}
265
275
266
276
needsPreventClick ( ) {
@@ -274,7 +284,7 @@ class ScrollView extends Component {
274
284
//
275
285
// This method determines whether either of these cases apply.
276
286
let isFinishingDragging = this . scroller . __isDragging ;
277
- let wasAnimatingWithMomentum = Math . abs ( this . _decelerationVelocityY ) > 2 ;
287
+ let wasAnimatingWithMomentum = this . _wasScrollingAtTouchStart && Math . abs ( this . _decelerationVelocityY ) > 2 ;
278
288
return isFinishingDragging || wasAnimatingWithMomentum ;
279
289
}
280
290
0 commit comments