diff --git a/examples/app/FeatureTestConsole.js b/examples/app/FeatureTestConsole.js index 482b5f34..414bb4f4 100644 --- a/examples/app/FeatureTestConsole.js +++ b/examples/app/FeatureTestConsole.js @@ -27,6 +27,9 @@ const initialStateSwipeable = { rotationAngle: 0, }; const initialStateApplied = { + showHook: true, + showComponent: true, + showOnSwipeds: false, onSwipingApplied: true, onSwipedApplied: true, onSwipedLeftApplied: true, @@ -100,6 +103,9 @@ export default class Main extends Component { swipingDirection, swipedDirection, delta, + showHook, + showComponent, + showOnSwipeds, onSwipingApplied, onSwipedApplied, persistEvent, @@ -129,7 +135,7 @@ export default class Main extends Component {
Test react-swipeable features.
- See output below and check the console for 'onSwiping' and 'onSwiped' callback output(open dev tools)

You can also 'toggle' the swip(ed/ing) props being applied to this container below.
- - } + {showHook && See output below and check the console for 'onSwiping' and 'onSwiped' callback output(open dev tools)

You can also 'toggle' the swip(ed/ing) props being applied to this container below.
- + } @@ -185,9 +191,26 @@ export default class Main extends Component { - + + {showOnSwipeds && + + } - -
Applied?ActionOutput
onSwiping Direction{swipingDirection}
↓ Below ↓ + (e.preventDefault(),this.updateValue('showOnSwipeds', !showOnSwipeds))}> + {showOnSwipeds ? '↑ Hide ↑' : '↓ Show ↓'} + + onSwiped Direction{swipedDirection}
+ + + + + + + {DIRECTIONS.map(this._renderAppliedDirRow.bind(this))} + +
onSwiped
Applied?Direction
+
delta: @@ -228,15 +251,24 @@ export default class Main extends Component { onChange={(e)=>this.updateValue('persistEvent', e.target.checked)}/>
- - - - - - - {DIRECTIONS.map(this._renderAppliedDirRow.bind(this))} + + + + + + + +
onSwiped
Applied?Direction
Show Hook Example: + this.updateValue('showHook', e.target.checked)}/> +
Show Component Example: + this.updateValue('showComponent', e.target.checked)}/> +
diff --git a/src/index.js b/src/index.js index 1bab740e..66fc3da5 100644 --- a/src/index.js +++ b/src/index.js @@ -47,12 +47,51 @@ function rotateXYByAngle(pos, angle) { } const getTouchHandlerOption = props => { - if (props.touchHandlerOption) return props.touchHandlerOption + if (typeof props.touchHandlerOption !== 'undefined') + return props.touchHandlerOption return props.preventDefaultTouchmoveEvent ? { passive: false } : { passive: true } } +const noop = () => {} +let touchMoveListenerSetup = false +let handlerToCall = noop +let touchMoveHandlerOption = {} +const setTouchMoveHandler = newH => (handlerToCall = newH) +const touchMoveHandler = e => { + handlerToCall(e) +} +const setupTouchMoveListener = touchHandlerOption => { + // cleanup and reset if preventDefaultTouchMoveEvent changed + if (typeof touchHandlerOption === 'object' && touchMoveListenerSetup) { + if (touchHandlerOption.passive !== touchMoveHandlerOption.passive) { + cleanUp() + } + } + // setup a single eventListener for 'touchmove' + if (!touchMoveListenerSetup) { + touchMoveHandlerOption = touchHandlerOption + document.addEventListener( + touchMove, + touchMoveHandler, + touchMoveHandlerOption + ) + touchMoveListenerSetup = true + } +} + +// clean up the single 'touchmove' eventListener +const cleanUp = () => { + document.removeEventListener( + touchMove, + touchMoveHandler, + touchMoveHandlerOption + ) + touchMoveListenerSetup = false + handlerToCall = noop +} + function getHandlers(set, props) { const onStart = event => { // if more than a single touch don't track, for now... @@ -131,8 +170,8 @@ function getHandlers(set, props) { } if (props.trackTouch) { const touchHandlerOption = getTouchHandlerOption(props) - document.addEventListener(touchMove, onMove, touchHandlerOption) document.addEventListener(touchEnd, onUp, touchHandlerOption) + setTouchMoveHandler(onMove) } onStart(e) } @@ -144,7 +183,6 @@ function getHandlers(set, props) { } if (props.trackTouch) { const touchHandlerOption = getTouchHandlerOption(props) - document.removeEventListener(touchMove, onMove, touchHandlerOption) document.removeEventListener(touchEnd, onUp, touchHandlerOption) } } @@ -154,6 +192,11 @@ function getHandlers(set, props) { onEnd(e) } + if (props.trackTouch) { + const touchHandlerOption = getTouchHandlerOption(props) + setupTouchMoveListener(touchHandlerOption) + } + const output = {} if (props.trackMouse) { output.onMouseDown = onDown @@ -173,6 +216,9 @@ export function useSwipeable(props) { ...currentProps }) ) + React.useEffect(() => { + return () => cleanUp() + }, []) return spread(props) } @@ -204,6 +250,10 @@ export class Swipeable extends React.PureComponent { this._set = cb => (this._state = cb(this._state)) } + componentWillUnmount() { + cleanUp() + } + render() { const { className,