@@ -3,7 +3,7 @@ import React from 'react';
33import PropTypes from 'prop-types' ;
44import ReactDOM from 'react-dom' ;
55import { matchesSelectorAndParentsTo , addEvent , removeEvent , addUserSelectStyles , getTouchIdentifier ,
6- removeUserSelectStyles , styleHacks } from './utils/domFns' ;
6+ removeUserSelectStyles } from './utils/domFns' ;
77import { createCoreData , getControlPosition , snapToGrid } from './utils/positionFns' ;
88import { dontSetMe } from './utils/shims' ;
99import log from './utils/log' ;
@@ -226,6 +226,12 @@ export default class DraggableCore extends React.Component<DraggableCoreProps, D
226226
227227 componentDidMount ( ) {
228228 this . mounted = true ;
229+ // Touch handlers must be added with {passive: false} to be cancelable.
230+ // https://developers.google.com/web/updates/2017/01/scrolling-intervention
231+ const thisNode = ReactDOM . findDOMNode ( this ) ;
232+ if ( thisNode ) {
233+ addEvent ( thisNode , eventsFor . touch . start , this . onTouchStart , { passive : false } ) ;
234+ }
229235 }
230236
231237 componentWillUnmount ( ) {
@@ -239,6 +245,7 @@ export default class DraggableCore extends React.Component<DraggableCoreProps, D
239245 removeEvent ( ownerDocument , eventsFor . touch . move , this . handleDrag ) ;
240246 removeEvent ( ownerDocument , eventsFor . mouse . stop , this . handleDragStop ) ;
241247 removeEvent ( ownerDocument , eventsFor . touch . stop , this . handleDragStop ) ;
248+ removeEvent ( thisNode , eventsFor . touch . start , this . onTouchStart , { passive : false } ) ;
242249 if ( this . props . enableUserSelectHack ) removeUserSelectStyles ( ownerDocument ) ;
243250 }
244251 }
@@ -265,6 +272,10 @@ export default class DraggableCore extends React.Component<DraggableCoreProps, D
265272 return ;
266273 }
267274
275+ // Prevent scrolling on mobile devices, like ipad/iphone.
276+ // Important that this is after handle/cancel.
277+ if ( e . type === 'touchstart' ) e . preventDefault ( ) ;
278+
268279 // Set touch identifier in component state if this is a touch event. This allows us to
269280 // distinguish between individual touches on multitouch screens by identifying which
270281 // touchpoint was set to this element.
@@ -309,9 +320,6 @@ export default class DraggableCore extends React.Component<DraggableCoreProps, D
309320
310321 handleDrag : EventHandler < MouseTouchEvent > = ( e ) => {
311322
312- // Prevent scrolling on mobile devices, like ipad/iphone.
313- if ( e . type === 'touchmove' ) e . preventDefault ( ) ;
314-
315323 // Get the current drag point from the event. This is used as the offset.
316324 const position = getControlPosition ( e , this . state . touchIdentifier , this ) ;
317325 if ( position == null ) return ;
@@ -418,13 +426,15 @@ export default class DraggableCore extends React.Component<DraggableCoreProps, D
418426 // Reuse the child provided
419427 // This makes it flexible to use whatever element is wanted (div, ul, etc)
420428 return React . cloneElement ( React . Children . only ( this . props . children ) , {
421- style : styleHacks ( this . props . children . props . style ) ,
429+ style : this . props . children . props . style ,
422430
423431 // Note: mouseMove handler is attached to document so it will still function
424432 // when the user drags quickly and leaves the bounds of the element.
425433 onMouseDown : this . onMouseDown ,
426- onTouchStart : this . onTouchStart ,
427434 onMouseUp : this . onMouseUp ,
435+ // onTouchStart is added on `componentDidMount` so they can be added with
436+ // {passive: false}, which allows it to cancel. See
437+ // https://developers.google.com/web/updates/2017/01/scrolling-intervention
428438 onTouchEnd : this . onTouchEnd
429439 } ) ;
430440 }
0 commit comments