Last active
March 26, 2020 23:23
-
-
Save aneudy1702/ba4094324ebcfbb26721cafc87026ecd to your computer and use it in GitHub Desktop.
React component to lock window scroll while users are horizontally swiping within the container. for example when swiping through a carousel.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { useRef } from 'react'; | |
import get from 'lodash.get'; | |
import throttle from 'lodash.throttle'; | |
const getTouchEndX = event => get(event, 'changedTouches[0].screenX') || 0; | |
const preventDefault = event => { | |
event.preventDefault(); | |
event.returnValue = false; | |
return false; | |
}; | |
const allowWindowScrolling = (shouldScroll = true) => { | |
const action = shouldScroll ? 'removeEventListener' : 'addEventListener'; | |
window[action]('touchmove', preventDefault, { passive: false }); | |
}; | |
export const PreventVerticalScrollingWhileSwiping = React.memo( | |
({ children, ...props }) => { | |
const touchStartX = useRef(0); | |
const touchEndX = useRef(0); | |
const timeToResetScrolling = 200; | |
const resetId = useRef(); | |
const onStart = throttle(event => { | |
touchStartX.current = getTouchEndX(event); | |
}); | |
const onMove = throttle(event => { | |
touchEndX.current = getTouchEndX(event); | |
const swipeDistanceHorizontal = touchEndX.current - touchStartX.current; | |
const isSwiping = Math.abs(swipeDistanceHorizontal) > 5; | |
// Allow Window Scrolling if no Horizontal Swipe is in progress | |
allowWindowScrolling(!isSwiping); | |
if (isSwiping) { | |
// Re-enable Window scrolling after the configured period | |
clearTimeout(resetId.current); | |
resetId.current = setTimeout(allowWindowScrolling, timeToResetScrolling); | |
} | |
}); | |
return ( | |
<div onTouchStart={onStart} onTouchMove={onMove} {...props}> | |
{children} | |
</div> | |
); | |
} | |
); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment