react-native-web
react-native-web copied to clipboard
ScrollView: momentum scroll events
Look into supporting momentum scroll events.
I guess that to add support for the scroll momentum callbacks there needs to be a way to detect if the scroll is done with momentum.
You could always check for the scroll speed, but that is not really the same thing as you call do a scroll movement fast without it having momentum.
Is anyone aware of any existing Javascript implementations where such gesture would be detected?
My initial thought is that if a scroll is initiated by a touch, and scroll events are still firing while there is no active touch, we're in a "momentum" phase of the scroll. I don't think momentum events can exist for mouse/wheel-triggered scrolls. And the drag start event would fire when touch-scrolling starts, and drag end would fire when touch-scrolling ends. But would have to check when the events fire for native to confirm.
I don't think momentum events can exist for mouse/wheel-triggered scrolls
At least on macos with a trackpad you can experience them in all browsers.
Might this help to finish touchable support as some issues with those might be related to some missing events (eg: for scroll responder?)
https://css-tricks.com/snippets/css/momentum-scrolling-on-ios-overflow-elements/
me too
For anyone needing a temp workaround I made a hook...
// hooks.js
export const useWebOnScroll = ({ onScroll, onScrollEnd }) => {
const lastScrollEvent = useRef(null);
const scrollEndTimeout = useRef(null);
const handleWebScroll = event => {
onScroll(event);
const timestamp = Date.now();
if (scrollEndTimeout.current) {
clearTimeout(scrollEndTimeout.current);
}
if (lastScrollEvent.current) {
// Scroll ended
scrollEndTimeout.current = setTimeout(() => {
if (lastScrollEvent.current === timestamp) {
lastScrollEvent.current = null;
onScrollEnd && onScrollEnd(event);
}
}, 500);
}
lastScrollEvent.current = timestamp;
};
useEffect(() => {
return () => {
scrollEndTimeout.current && clearTimeout(scrollEndTimeout.current);
};
}, []);
return handleWebScroll;
};
// Component.js
const Component = ({onScroll, onScrollEnd}) => {
const handleWebScroll = useWebOnScroll({ onScroll, onScrollEnd })
<ScrollView onScroll={Platform.select({ web: handleWebScroll, default: onScroll })} />
}
Anyone know if this has been fixed or if there's another way of achieving this effect on RN web?
Here's my solution: https://github.com/necolas/react-native-web/issues/2249#issuecomment-1736457705