Created
September 15, 2022 23:50
-
-
Save tzynwang/cc5bd3c9969dc4420fee88d11db987e8 to your computer and use it in GitHub Desktop.
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
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; | |
} |
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
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