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 } |