Skip to content

Instantly share code, notes, and snippets.

@chancity
Created October 9, 2020 16:36
Show Gist options
  • Save chancity/599f45c0e08eaaa5579e72a92741cfe0 to your computer and use it in GitHub Desktop.
Save chancity/599f45c0e08eaaa5579e72a92741cfe0 to your computer and use it in GitHub Desktop.
React scroll hook
import {useEffect, useState} from 'react';
export const DIRECTION = {
down: 'DOWN',
up: 'UP',
unset: 'UNSET',
};
const getDocumentBoundingClientRect = (documentElement) =>
typeof documentElement.getBoundingClientRect === 'function' ?
documentElement.getBoundingClientRect() :
{
top: 0,
left: 0,
};
const getDocumentElement = (isServer) =>
!isServer ?
document.documentElement
: {
scrollHeight: 0,
scrollWidth: 0,
getBoundingClientRect: getDocumentBoundingClientRect,
};
const getWindowSize = (isServer) => ({
innerHeight: !isServer ? window.innerHeight : 0,
innerWidth: !isServer ? window.innerWidth : 0,
});
const createScrollState = (lastScrollTop) => {
const isServer = !process.browser;
const documentElement = getDocumentElement(isServer);
const bodyBoundingRect = documentElement.getBoundingClientRect();
const windowSize = getWindowSize(isServer);
const scrollY = bodyBoundingRect.top;
const scrollX = bodyBoundingRect.left;
const scrollYMax = documentElement.scrollHeight - windowSize.innerHeight;
const scrollXMax = documentElement.scrollWidth - windowSize.innerWidth;
const scrollDirection = lastScrollTop > bodyBoundingRect.top ? DIRECTION.down : DIRECTION.up;
return {
scrollY,
scrollX,
scrollDirection,
scrollYMax,
scrollXMax,
}
};
const useWindowScroll = () => {
const [state, setState] = useState(createScrollState(0));
useEffect(() => {
const listener = () =>
setState(previousState =>
createScrollState(previousState.scrollY)
);
window.addEventListener('scroll', listener);
return () => {
window.removeEventListener('scroll', listener);
};
}, []);
return state;
};
export default useWindowScroll;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment