From 6ae68e948f9de0ba24fe95193221c90c6e19e57b Mon Sep 17 00:00:00 2001 From: Nicolas Gallagher Date: Sun, 11 Jun 2017 14:09:59 -0700 Subject: [PATCH] [fix] ScrollView passive event listener warning 'touchstart' and 'touchmove' listeners added to the document will default to 'passive:true' (so that calls to 'preventDefault' will be ignored). Source https://www.chromestatus.com/features/5093566007214080 To support 'scrollEnabled', listeners are bound to the underlying ScrollView DOM node to avoid being passive. Fix #477 --- src/components/ScrollView/ScrollViewBase.js | 43 +++++++++++++++------ 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/src/components/ScrollView/ScrollViewBase.js b/src/components/ScrollView/ScrollViewBase.js index 78e17b3f..671c23a2 100644 --- a/src/components/ScrollView/ScrollViewBase.js +++ b/src/components/ScrollView/ScrollViewBase.js @@ -7,6 +7,7 @@ */ import debounce from 'debounce'; +import findNodeHandle from '../../modules/findNodeHandle'; import View from '../View'; import ViewPropTypes from '../View/ViewPropTypes'; import React, { Component } from 'react'; @@ -69,8 +70,21 @@ export default class ScrollViewBase extends Component { _debouncedOnScrollEnd = debounce(this._handleScrollEnd, 100); _state = { isScrolling: false, scrollLastTick: 0 }; + _node = null; - _handlePreventableScrollEvent = (handler: Function) => { + componentDidMount() { + this._node && this._node.addEventListener('scroll', this._handleScroll); + this._node && this._node.addEventListener('touchmove', this._handlePreventableTouchMove); + this._node && this._node.addEventListener('wheel', this._handlePreventableWheel); + } + + componentWillUnmount() { + this._node && this._node.removeEventListener('scroll', this._handleScroll); + this._node && this._node.removeEventListener('touchmove', this._handlePreventableTouchMove); + this._node && this._node.removeEventListener('wheel', this._handlePreventableWheel); + } + + _createPreventableScrollHandler = (handler: Function) => { return (e: Object) => { if (!this.props.scrollEnabled) { e.preventDefault(); @@ -82,8 +96,15 @@ export default class ScrollViewBase extends Component { }; }; - _handleScroll = (e: SyntheticEvent) => { - e.persist(); + _handlePreventableTouchMove = (e: Object) => { + this._createPreventableScrollHandler(this.props.onTouchMove)(e); + }; + + _handlePreventableWheel = (e: Object) => { + this._createPreventableScrollHandler(this.props.onWheel)(e); + }; + + _handleScroll = (e: Object) => { e.stopPropagation(); const { scrollEventThrottle } = this.props; // A scroll happened, so the scroll bumps the debounce. @@ -120,6 +141,10 @@ export default class ScrollViewBase extends Component { } } + _setNodeRef = (element:View) => { + this._node = findNodeHandle(element); + }; + _shouldEmitScrollEvent(lastTick: number, eventThrottle: number) { const timeSinceLastTick = Date.now() - lastTick; return eventThrottle > 0 && timeSinceLastTick >= eventThrottle; @@ -130,8 +155,11 @@ export default class ScrollViewBase extends Component { /* eslint-disable */ onMomentumScrollBegin, onMomentumScrollEnd, + onScroll, onScrollBeginDrag, onScrollEndDrag, + onTouchMove, + onWheel, removeClippedSubviews, scrollEnabled, scrollEventThrottle, @@ -141,13 +169,6 @@ export default class ScrollViewBase extends Component { ...other } = this.props; - return ( - - ); + return ; } }