Browse Source

fix

affix-r
栗嘉男 1 year ago
parent
commit
2ae3305a2e
  1. 45
      components/affix/index.tsx
  2. 2
      package.json

45
components/affix/index.tsx

@ -44,14 +44,6 @@ enum AffixStatus {
Prepare, Prepare,
} }
export interface AffixState {
affixStyle?: React.CSSProperties;
placeholderStyle?: React.CSSProperties;
status: AffixStatus;
lastAffix: boolean;
prevTarget: Window | HTMLElement | null;
}
interface AffixRef { interface AffixRef {
updatePosition: ReturnType<typeof throttleByAnimationFrame>; updatePosition: ReturnType<typeof throttleByAnimationFrame>;
} }
@ -68,6 +60,7 @@ const Affix = React.forwardRef<AffixRef, AffixProps>((props, ref) => {
} = props; } = props;
const [lastAffix, setLastAffix] = useState<boolean>(false); const [lastAffix, setLastAffix] = useState<boolean>(false);
const [status, setStatus] = useState<AffixStatus>(AffixStatus.None);
const [affixStyle, setAffixStyle] = useState<React.CSSProperties>(); const [affixStyle, setAffixStyle] = useState<React.CSSProperties>();
const [placeholderStyle, setPlaceholderStyle] = useState<React.CSSProperties>(); const [placeholderStyle, setPlaceholderStyle] = useState<React.CSSProperties>();
const placeholderNodeRef = useRef<HTMLDivElement>(null); const placeholderNodeRef = useRef<HTMLDivElement>(null);
@ -89,7 +82,12 @@ const Affix = React.forwardRef<AffixRef, AffixProps>((props, ref) => {
); );
const measure = () => { const measure = () => {
if (!target || !fixedNodeRef.current || !placeholderNodeRef.current) { if (
status === AffixStatus.Prepare ||
!target ||
!fixedNodeRef.current ||
!placeholderNodeRef.current
) {
return; return;
} }
const placeholderRect = getTargetRect(placeholderNodeRef.current); const placeholderRect = getTargetRect(placeholderNodeRef.current);
@ -138,21 +136,30 @@ const Affix = React.forwardRef<AffixRef, AffixProps>((props, ref) => {
}); });
}; };
const updatePosition = throttleByAnimationFrame(() => { const prepareMeasure = () => {
// event param is used before. Keep compatible ts define here.
setStatus(AffixStatus.Prepare);
setAffixStyle(undefined);
setPlaceholderStyle(undefined);
};
const updatePosition = throttleByAnimationFrame(prepareMeasure);
const lazyUpdatePosition = throttleByAnimationFrame(() => {
// Check position change before measure to make Safari smooth // Check position change before measure to make Safari smooth
if (target && placeholderNodeRef.current) { if (target && placeholderNodeRef.current && affixStyle) {
const targetRect = getTargetRect(target); const targetRect = getTargetRect(target);
const placeholderRect = getTargetRect(placeholderNodeRef.current); const placeholderRect = getTargetRect(placeholderNodeRef.current);
const fixedTop = getFixedTop(placeholderRect, targetRect, memoOffsetTop); const fixedTop = getFixedTop(placeholderRect, targetRect, offsetTop);
const fixedBottom = getFixedBottom(placeholderRect, targetRect, offsetBottom); const fixedBottom = getFixedBottom(placeholderRect, targetRect, offsetBottom);
if ( if (
(fixedTop !== undefined && affixStyle?.top === fixedTop) || (fixedTop !== undefined && affixStyle.top === fixedTop) ||
(fixedBottom !== undefined && affixStyle?.bottom === fixedBottom) (fixedBottom !== undefined && affixStyle.bottom === fixedBottom)
) { ) {
return; return;
} }
} }
measure(); prepareMeasure();
}); });
React.useImperativeHandle(ref, () => ({ updatePosition })); React.useImperativeHandle(ref, () => ({ updatePosition }));
@ -160,8 +167,9 @@ const Affix = React.forwardRef<AffixRef, AffixProps>((props, ref) => {
useEffect(() => { useEffect(() => {
timerRef.current = setTimeout(() => { timerRef.current = setTimeout(() => {
TRIGGER_EVENTS.forEach((eventName) => { TRIGGER_EVENTS.forEach((eventName) => {
target?.addEventListener(eventName, updatePosition); target?.addEventListener(eventName, lazyUpdatePosition);
}); });
// updatePosition();
measure(); measure();
}); });
return () => { return () => {
@ -170,12 +178,13 @@ const Affix = React.forwardRef<AffixRef, AffixProps>((props, ref) => {
timerRef.current = null; timerRef.current = null;
} }
TRIGGER_EVENTS.forEach((eventName) => { TRIGGER_EVENTS.forEach((eventName) => {
target?.removeEventListener(eventName, updatePosition); target?.removeEventListener(eventName, lazyUpdatePosition);
}); });
updatePosition.cancel(); updatePosition.cancel();
lazyUpdatePosition.cancel();
}; };
}, [offsetTop, offsetBottom, customizeTarget, getTargetContainer]); }, [offsetTop, offsetBottom, customizeTarget, getTargetContainer]);
const [wrapSSR, hashId] = useStyle(affixPrefixCls); const [wrapSSR, hashId] = useStyle(affixPrefixCls);
const rootClassName = classNames(customizeRootClassName, hashId); const rootClassName = classNames(customizeRootClassName, hashId);

2
package.json

@ -124,7 +124,7 @@
"qrcode.react": "^3.1.0", "qrcode.react": "^3.1.0",
"rc-cascader": "~3.12.0", "rc-cascader": "~3.12.0",
"rc-checkbox": "~3.0.0", "rc-checkbox": "~3.0.0",
"rc-collapse": "~3.7.0", "rc-collapse": "^3.7.0",
"rc-dialog": "~9.1.0", "rc-dialog": "~9.1.0",
"rc-drawer": "~6.2.0", "rc-drawer": "~6.2.0",
"rc-dropdown": "~4.1.0", "rc-dropdown": "~4.1.0",

Loading…
Cancel
Save