Skip to content

Instantly share code, notes, and snippets.

@dance2die
Last active August 23, 2019 02:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dance2die/f813bd90dcf680bf67fdde163dca3a89 to your computer and use it in GitHub Desktop.
Save dance2die/f813bd90dcf680bf67fdde163dca3a89 to your computer and use it in GitHub Desktop.
function useObserveBottomSentinels(
bottomSentinelRef,
{ events: { onStuck, onUnstuck, onChange } }
) {
const { stickyRefs, containerRef } = useStickyState();
useEffect(() => {
if (!containerRef) return;
if (!containerRef.current) return;
const root = containerRef.current;
const options = { threshold: [1], root };
const observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
const target = stickyRefs.get(entry.target);
const targetRect = target.getBoundingClientRect();
const bottomSentinelRect = entry.boundingClientRect;
const rootBounds = entry.rootBounds;
const intersectionRatio = entry.intersectionRatio;
let type = undefined;
if (
bottomSentinelRect.top >= rootBounds.top &&
bottomSentinelRect.bottom <= rootBounds.bottom &&
intersectionRatio === 1 &&
targetRect.y === 0
) {
type = "stuck";
onStuck(target);
}
if (bottomSentinelRect.top <= rootBounds.top) {
type = "unstuck";
onUnstuck(target);
}
type && onChange({ type, target });
});
}, options);
const sentinel = bottomSentinelRef.current;
sentinel && observer.observe(sentinel);
return () => {
observer.unobserve(sentinel);
};
}, [bottomSentinelRef, onChange, onStuck, onUnstuck, stickyRefs, containerRef]);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment