const ref = useRef(null);
const [screenHeight, setScreenHeight] = useState(0);
const [startOffset, setStartOffset] = useState(0);
const [start, setStart] = useState(0);
const itemSize = 100;
const listHeight = itemSize * listData.length;
const transform = `translate3d(0,${startOffset}px,0)`;
const visibleCount = Math.ceil(screenHeight / itemSize);
const visibleData = listData.slice(start, start + visibleCount);
useEffect(() => {
setScreenHeight(ref.current.clientHeight);
setStart(0)
}, []);
return (
<div>
<div
ref={ref}
onScroll={(e) => {
let scrollTop = ref.current.scrollTop;
setStart(Math.floor(scrollTop / itemSize));
setStartOffset(scrollTop - (scrollTop % itemSize));
}}
style={{
height: 600,
overflow: 'auto',
position: 'relative',
WebkitOverflowScrolling: 'touch',
backgroundColor: "pink"
}}
>
<div
style={{
height: listHeight,
position: 'absolute',
left: 0,
top: 0,
right: 0,
zIndex: -1
}}
></div>
<div
style={{
transform: transform,
left: 0,
right: 0,
top: 0,
position: 'absolute',
textAlign: 'center'
}}
>
{visibleData.map((item) => (
<div
key={item.id}
style={{
height: itemSize,
lineHeight: `${itemSize}px`,
color: '#555',
boxSizing: 'border-box',
borderBottom: '1px solid #999'
}}
>
{item.value}
</div>
))}
</div>
</div>
</div>
);
};
参考:juejin.cn/post/684490…