<div id='root'></div>
// 创建随机数
const createRandom = () => Math.floor(Math.random() * 1000);
// 创建一个图片url集合
const createSrc = (num = 10) => new Array(num).fill(0).map(() => {
const index = createRandom();
return `https://picsum.photos/200?random=${index}`;
});
// 检查节点是否出现在视口
const checkVisible = (node, callback) => {
const {top, height} = node.getBoundingClientRect();
const innerHeight = window.innerHeight;
top <= innerHeight && (top + height) > 0 && callback(true);
}
// 懒加载实现
const LazyLoad = (props) => {
const ref = React.useRef(null);
const [visible, setVisible] = React.useState(false);
// 首次渲染,加载视口内的图片
React.useEffect(() => {
const node = ref.current
if (node) {
checkVisible(node, setVisible);
}
}, []);
// 监听窗口滚动事件
React.useEffect(() => {
const node = ref.current
const lazyLoadHandle = () => {
checkVisible(node, setVisible);
}
if (node) {
window.addEventListener('scroll', lazyLoadHandle)
}
return () => window.removeEventListener('scroll', lazyLoadHandle);
}, []);
return(
<div ref={ref}>
{visible ? props.children : (<div style={{height: props.height}} />)}
</div>
)
}
// 懒加载组件应用
const LazyLoadImage = ({ src }) => {
return (
<LazyLoad height='200px'>
<img alt="" src={src} />
</LazyLoad>
);
};
function App() {
return(
<div>
{createSrc(1000).map((item, index) => (
<LazyLoadImage src={item} key={index} />
))}
</div>
)
}
ReactDOM.render(<App />, document.getElementById('root'))
View Compiled
This Pen doesn't use any external CSS resources.