All files / src/_util use-parent-scroll.ts

18.18% Statements 4/22
30% Branches 3/10
50% Functions 3/6
14.29% Lines 3/21

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52                    306x 305x 305x                                                                              
import { useEffect, RefObject } from "react";
import {
  getScrollParent,
  getParentNode,
} from "popper.js/dist/esm/popper-utils";
 
export function useParentScroll(
  elementRef: RefObject<HTMLElement>,
  onScroll: (event: Event) => void
) {
  useEffect(() => {
    Eif (!elementRef.current || !onScroll) {
      return () => null;
    }
 
    const dom = elementRef.current;
 
    // https://github.com/FezVrasta/popper.js/blob/master/packages/popper/src/utils/setupEventListeners.js
    let scrollParents: (HTMLElement | Window)[] = [];
    let scrollParent: HTMLElement = getScrollParent(dom);
 
    function handleScroll(event: Event) {
      // IE 元素内部滚动会冒泡至 window
      // 导致非 scrollParent 元素滚动触发 onScroll
      if (event.target === event.currentTarget) {
        onScroll(event);
      }
    }
 
    while (scrollParent) {
      const isBody = scrollParent.nodeName === "BODY";
      const target = isBody
        ? scrollParent.ownerDocument.defaultView
        : scrollParent;
      target.addEventListener("scroll", handleScroll, { passive: true });
      scrollParents.push(target);
      if (isBody) {
        break;
      }
      scrollParent = getScrollParent(getParentNode(scrollParent));
    }
    scrollParent = null;
 
    return () => {
      scrollParents.forEach(parent =>
        parent.removeEventListener("scroll", handleScroll)
      );
      scrollParents = null;
    };
  }, [Boolean(onScroll), elementRef.current]); // eslint-disable-line react-hooks/exhaustive-deps
}