Skip to content

Instantly share code, notes, and snippets.

@codler
Last active September 11, 2024 07:28
Show Gist options
  • Save codler/7237990baef87ef00b9e1f7989c24ee5 to your computer and use it in GitHub Desktop.
Save codler/7237990baef87ef00b9e1f7989c24ee5 to your computer and use it in GitHub Desktop.
React hook check if element is in viewport
import { useState, useEffect, RefObject, useCallback } from "react";
function isElementInViewport(el: Element) {
var rect = el.getBoundingClientRect();
return (
rect.bottom >= 0 &&
rect.right >= 0 &&
rect.top <= (window.innerHeight || document.documentElement.clientHeight) &&
rect.left <= (window.innerWidth || document.documentElement.clientWidth)
);
}
export function useInViewport(ref: RefObject<Element>) {
const [isVisible, setIsVisible] = useState(true);
const update = useCallback(() => {
if (ref.current) {
setIsVisible(isElementInViewport(ref.current));
}
}, [ref]);
useEffect(() => {
["scroll", "load", "DOMContentLoaded", "resize", "click"].forEach(type => {
window.addEventListener(type, update);
});
return () => {
["scroll", "load", "DOMContentLoaded", "resize", "click"].forEach(type => {
window.removeEventListener(type, update);
});
};
}, [update]);
return { isVisible, update };
}
@pchr-srf
Copy link

Nice. I'd suggest using IntersectionObserver though, as it's a bit more resource-friendly 🙂
E.g. https://usehooks-ts.com/react-hook/use-intersection-observer

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment