<AutoFixed
// 距离顶部为 20px 吸顶
top="0px"
// 占位高度,也就是 children 的高度
height="56px"
// fixed状态改变时
onFixedChange={(isFixed) => {
setIsFixed(isFixed);
}}
// fixed状态需要添加的className
fixedClassName=""
// fixed状态需要添加的style
fixedStyle={{ color: 'red' }}
root={containerRef?.current}
>
<div
className={styles.tabsBoxWrap}
style={{
width: isFixed ? '100vw' : '100%',
}}>
<div className={styles.tabsBox}>
<Tabs
defaultActiveKey="1"
tabBarGutter={'96px'}
tabBarStyle={tabsStyle}
items={items}
onChange={(v, e) => onChange(v, e)}
/>
</div>
</div>
</AutoFixed>
import React, { useEffect, useRef } from 'react';
import { useIntersection } from './hooks/useIntersection';
const AutoFixed = (props) => {
const {
alwaysFixed,
top,
bottom,
style,
height,
root,
zIndex = 100,
children,
className,
fixedClassName,
fixedStyle,
onFixedChange,
...rest
} = props;
const isFiexdTop = !bottom;
const wrapperRef = useRef(null);
const options = {
rootMargin: isFiexdTop
? `-${top || '0px'} 0px 10000px 0px`
: `0px 0px -${bottom || '0px'} 0px`,
root,
};
const intersection = useIntersection({ el: wrapperRef, options });
useEffect(() => {
onFixedChange?.(intersection);
console.log('需要吸顶吗', intersection);
}, [intersection]);
return (
<div
style={{ ...style, height }}
{...rest}
className={`${className}${intersection ? ' fixedClassName' : ''}`}
ref={wrapperRef}>
<div
style={{
height,
position: intersection ? 'fixed' : 'initial',
top: isFiexdTop ? top || 0 : undefined,
bottom: isFiexdTop ? undefined : bottom || 0,
zIndex: zIndex,
...(intersection ? fixedStyle : {}),
}}>
{children}
</div>
</div>
);
};
export default AutoFixed;
import React, { useEffect, useState } from 'react';
export function useIntersection(props) {
const { el, options } = props;
const [intersection, setIntersection] = useState(true);
useEffect(() => {
if (!el.current) return;
const intersectionObserver = new IntersectionObserver(
function (entries) {
console.log(entries);
setIntersection(entries[0].intersectionRatio === 1);
},
{ ...options, threshold: [1] }
);
intersectionObserver.observe(el.current);
return () => {
intersectionObserver.disconnect();
};
}, [el.current]);
return !intersection;
}