React - check if element is visible in DOM

前端 未结 5 2027
刺人心
刺人心 2020-12-25 12:24

I\'m building a form - series of questions (radio buttons) the user needs to answer before he can move on to the next screen. For fields validation I\'m using yup (npm packa

5条回答
  •  时光取名叫无心
    2020-12-25 12:43

    Based on Avraam's answer I wrote a Typescript-compatible small hook to satisfy the actual React code convention.

    import { createRef, useEffect, useState } from "react";
    import throttle from "lodash.throttle";
    
    /**
     * Check if an element is in viewport
    
     * @param {number} offset - Number of pixels up to the observable element from the top
     * @param {number} throttleMilliseconds - Throttle observable listener, in ms
     */
    export default function useVisibility(
      offset = 0,
      throttleMilliseconds = 100
    ): [Boolean, React.RefObject] {
      const [isVisible, setIsVisible] = useState(false);
      const currentElement = createRef();
    
      const onScroll = throttle(() => {
        if (!currentElement.current) {
          setIsVisible(false);
          return;
        }
        const top = currentElement.current.getBoundingClientRect().top;
        setIsVisible(top + offset >= 0 && top - offset <= window.innerHeight);
      }, throttleMilliseconds);
    
      useEffect(() => {
        document.addEventListener('scroll', onScroll, true);
        return () => document.removeEventListener('scroll', onScroll, true);
      });
    
      return [isVisible, currentElement];
    }
    
    

    Usage example:

    const Example: FC = () => {
      const [ isVisible, currentElement ] = useVisibility(100);
    
      return ;
    };
    
    

    You can find the example on Codesandbox. I hope you will find it helpful!

提交回复
热议问题