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 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | 1x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x | import React, { useRef, useState, useEffect, useMemo, forwardRef, useImperativeHandle, } from "react"; import { AffixProps } from "./AffixProps"; import { getTarget, getRect, throttle, getFixed } from "./util"; import { addListener, removeListener } from "./AffixManager"; import { uuid } from "../_util/uuid"; export interface AffixHandles { update: () => void; } export const Affix = forwardRef(function Affix( { offsetTop, offsetBottom, target = window, children, style, className, }: AffixProps, ref: React.Ref<AffixHandles> ) { // 默认吸顶 Iif (typeof offsetTop === "undefined" && typeof offsetBottom === "undefined") { offsetTop = 0; // eslint-disable-line no-param-reassign } const affixRef = useRef<HTMLDivElement>(null); const placeholderRef = useRef<HTMLDivElement>(null); const [affixStyle, setAffixStyle] = useState<React.CSSProperties>(undefined); const [placeholderStyle, setPlaceholderStyle] = useState<React.CSSProperties>( undefined ); const update = useMemo( () => throttle(() => { const placeholder = placeholderRef.current; if (!placeholder) { return; } const placeholderRect = getRect(placeholder); const sizeStyle = { width: placeholderRect.width, height: placeholderRect.height, }; setPlaceholderStyle(sizeStyle); if (typeof offsetTop !== "undefined") { const top = getFixed(target, placeholder, offsetTop); setAffixStyle( typeof top !== "undefined" ? Object.assign({ position: "fixed", zIndex: 10, top }, sizeStyle) : undefined ); } else { const bottom = getFixed(target, placeholder, offsetBottom, false); setAffixStyle( typeof bottom !== "undefined" ? Object.assign( { position: "fixed", zIndex: 10, bottom }, sizeStyle ) : undefined ); } }), [offsetBottom, offsetTop, target] ); useImperativeHandle(ref, () => ({ update, })); useEffect(() => { update(); const id = uuid(); const targetElement = getTarget(target); addListener(targetElement, id, update); return () => removeListener(targetElement, id); }, [offsetBottom, offsetTop, target, update]); return ( <div ref={placeholderRef}> {affixStyle && <div style={placeholderStyle} />} <div ref={affixRef} className={className} style={{ ...(affixStyle || {}), ...(style || {}) }} > {children} </div> </div> ); }); |