CODE
useVerticalScrollHandler.ts
interface Params {
onScroll?: () => void;
onScrollDown?: () => void;
onScrollUp?: () => void;
}
const useVerticalScrollHandler = ({ onScroll, onScrollDown, onScrollUp }: Params) => {
const yPos = useRef(typeof window === "undefined" ? 0 : window.scrollY);
const throttleScroll = useMemo(() => {
const handleScroll = () => {
const deltaY = window.scrollY - yPos.current;
yPos.current = window.scrollY;
const direction = scrollY > 0 && deltaY >= 0 ? "DOWN" : "UP";
onScroll?.();
switch (direction) {
case "DOWN":
onScrollDown?.();
break;
case "UP":
onScrollUp?.();
break;
}
};
return throttle(throttledHandleScroll, 100);
}, [onScroll, onScrollDown, onScrollUp]);
useEffect(() => {
document.addEventListener("scroll", throttleScroll);
return () => {
document.removeEventListener("scroll", throttleScroll);
};
}, [throttleScroll]);
};
useVerticalScrollHandler.ts
interface Params {
onScroll?: () => void;
onScrollDown?: () => void;
onScrollUp?: () => void;
}
const useVerticalScrollHandler = ({ onScroll, onScrollDown, onScrollUp }: Params) => {
const yPos = useRef(typeof window === "undefined" ? 0 : window.scrollY);
const throttleScroll = useMemo(() => {
const handleScroll = () => {
const deltaY = window.scrollY - yPos.current;
yPos.current = window.scrollY;
const direction = scrollY > 0 && deltaY >= 0 ? "DOWN" : "UP";
onScroll?.();
switch (direction) {
case "DOWN":
onScrollDown?.();
break;
case "UP":
onScrollUp?.();
break;
}
};
return throttle(throttledHandleScroll, 100);
}, [onScroll, onScrollDown, onScrollUp]);
useEffect(() => {
document.addEventListener("scroll", throttleScroll);
return () => {
document.removeEventListener("scroll", throttleScroll);
};
}, [throttleScroll]);
};
HOW TO USE
아래 방향 스크롤 이동중에만 노출하는 버튼
const ScrollToTopButton = () => {
const [isVisible, setIsVisible] = useState(false);
const show = useCallback(() => {
setIsVisible(true);
}, []);
const hide = useCallback(() => {
setIsVisible(false);
}, []);
useVerticalScrollHandler({ onScrollDown: show, onScrollUp: hide });
return (
<Flex justifyContents="center" alignItems="center" tagName="button" className={`${!isVisible ? "hidden" : ""}`}>
<IoIosArrowUp />
<span className="font-semibold">TOP</span>
</Flex>
);
};
아래 방향 스크롤 이동중에만 노출하는 버튼
const ScrollToTopButton = () => {
const [isVisible, setIsVisible] = useState(false);
const show = useCallback(() => {
setIsVisible(true);
}, []);
const hide = useCallback(() => {
setIsVisible(false);
}, []);
useVerticalScrollHandler({ onScrollDown: show, onScrollUp: hide });
return (
<Flex justifyContents="center" alignItems="center" tagName="button" className={`${!isVisible ? "hidden" : ""}`}>
<IoIosArrowUp />
<span className="font-semibold">TOP</span>
</Flex>
);
};