Skip to content

Instantly share code, notes, and snippets.

@tzynwang
Created September 15, 2022 23:50
Show Gist options
  • Save tzynwang/cc5bd3c9969dc4420fee88d11db987e8 to your computer and use it in GitHub Desktop.
Save tzynwang/cc5bd3c9969dc4420fee88d11db987e8 to your computer and use it in GitHub Desktop.
import { useEffect, useState, useCallback } from 'react';
import { debounce } from 'lodash';
export default function useElementIsScrollDown(
elementRef: React.MutableRefObject<Element | null>,
delay: number = 100
): boolean {
/* States */
const [oldScrollTop, setOldScrollTop] = useState<number>(0);
const [isDown, setIsDown] = useState<boolean>(false);
/* Functions */
const logScrollTop = useCallback(
(e: Event): void => {
const target = e.target as Element;
const newScrollTop = target.scrollTop;
if (newScrollTop > oldScrollTop) {
setIsDown(true);
} else {
setIsDown(false);
}
setOldScrollTop(newScrollTop);
},
[oldScrollTop]
);
const debouncedLogScrollTop = debounce(logScrollTop, delay);
/* Hooks */
useEffect(() => {
const element = elementRef.current;
element?.addEventListener('scroll', debouncedLogScrollTop);
return () => {
element?.removeEventListener('scroll', debouncedLogScrollTop);
};
}, [elementRef, debouncedLogScrollTop]);
/* Main */
return isDown;
}
import { useState, useEffect, useCallback } from 'react';
import { debounce } from 'lodash';
export default function useElementScrollPercentage(
elementRef: React.MutableRefObject<Element | null>,
delay: number = 100
): number {
/* States */
const [percentage, setPercentage] = useState<number>(0);
/* Functions */
const calculatePercentage = useCallback((e: Event): void => {
const target = e.target as Element;
const { scrollTop, scrollHeight, clientHeight } = target;
const percent = (scrollTop / (scrollHeight - clientHeight)) * 100;
setPercentage(Math.round(percent));
}, []);
const debouncedCalcPercentage = debounce(calculatePercentage, delay);
/* Hooks */
useEffect(() => {
const element = elementRef.current;
element?.addEventListener('scroll', debouncedCalcPercentage);
return () =>
element?.removeEventListener('scroll', debouncedCalcPercentage);
}, [elementRef, debouncedCalcPercentage]);
/* Main */
return percentage;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment