@supunlakmal/hooks
Version:
A collection of reusable React hooks
59 lines • 2.26 kB
JavaScript
import { useState, useEffect, useRef } from 'react';
import { useEventListener } from '../event-handling/useEventListener';
const isBrowser = typeof window !== 'undefined';
function getScrollPosition(element) {
if (!isBrowser) {
return { x: 0, y: 0 };
}
const target = element
? 'current' in element
? element.current
: element
: window;
if (!target) {
return { x: 0, y: 0 };
}
if (target === window) {
return { x: window.scrollX, y: window.scrollY };
}
else if (target instanceof Element) {
return { x: target.scrollLeft, y: target.scrollTop };
}
else {
// Should not happen with current types, but fallback
return { x: 0, y: 0 };
}
}
/**
* Custom hook to track the scroll position of the window or a specific element.
*
* @param {RefObject<Element> | Window | null} [element] - The target element or window to track scroll position for. Defaults to window.
* @param {number} [throttleMs=100] - Throttle time in milliseconds to limit scroll event handling. Set to 0 to disable throttling.
* @returns {ScrollPosition} An object containing the current x and y scroll position.
*/
export const useScrollPosition = (element, throttleMs = 100) => {
const [position, setPosition] = useState(() => getScrollPosition(element));
const throttleTimeout = useRef(null);
const handleScroll = () => {
setPosition(getScrollPosition(element));
throttleTimeout.current = null; // Clear timeout ref after execution
};
const throttledHandleScroll = () => {
if (throttleMs <= 0) {
handleScroll();
return;
}
if (throttleTimeout.current === null) {
throttleTimeout.current = setTimeout(handleScroll, throttleMs);
}
};
// Determine the event target
const target = element !== null && element !== void 0 ? element : window;
useEventListener('scroll', throttledHandleScroll, target);
// Re-calculate on element change
useEffect(() => {
setPosition(getScrollPosition(element));
}, [element]); // Depend on the element/ref object itself
return position;
};
//# sourceMappingURL=useScrollPosition.js.map