Created
April 9, 2024 13:01
-
-
Save saltnpixels/7e8a322d3156f6a4da1736caaa66af12 to your computer and use it in GitHub Desktop.
Sticky Intersect Observer
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
const useStickyScroll = ( | |
{ | |
elementRef, | |
containerRef | |
}: {elementRef: any; containerRef?: any; onScroll?: (y: number) => void}, | |
dependencies: any[] = [] | |
) => { | |
const [isSticky, setIsSticky] = useState(false); | |
// Use useRef for the callback to avoid triggering re-renders | |
const onCallbackRef = useRef<(y: number) => void>(); | |
// Method to update the callback | |
const onIntersectScroll = useCallback((cb?: (y: number) => void) => { | |
if (cb) { | |
onCallbackRef.current = cb; | |
} | |
}, []); | |
useLayoutEffect(() => { | |
if (!containerRef) { | |
containerRef.current = window ? window : null; | |
} | |
if (!elementRef.current || !containerRef.current) { | |
return; | |
} | |
// full threshhold to get every moment of intersections | |
const threshold = []; | |
if (onCallbackRef.current) { | |
for (let i = 0; i <= 1.0; i += 0.01) { | |
threshold.push(i); | |
} | |
} else { | |
threshold.push(0, 1); | |
} | |
const observer = new IntersectionObserver( | |
(entries) => { | |
entries.forEach((entry) => { | |
const visiblePct = Math.floor(entry.intersectionRatio * 100); | |
setIsSticky(entry.intersectionRatio < 1); | |
onCallbackRef.current?.(visiblePct); | |
}); | |
}, | |
{ | |
root: containerRef.current, // Use the container as the root | |
rootMargin: '-1px 0px 0px 0px', // Adjust this value as needed | |
threshold: threshold // Trigger when the first pixel is out of view | |
} | |
); | |
observer.observe(elementRef.current); | |
return () => { | |
if (observer) { | |
observer.disconnect(); | |
} | |
}; | |
}, [elementRef.current, containerRef.current, ...dependencies]); | |
return {isSticky, onIntersectScroll}; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment