懒加载实现原理: 交叉检查对象
前端图片的懒加载包括两类:图片、背景图
代码示例: react
step1: 定义观察器
let lazyImageObserver = null;
if ('IntersectionObserver' in window) {
let _lazyImageObserver = new IntersectionObserver(function (entries, observer) {
entries.forEach(function (entry) {
if (entry.isIntersecting) {
let lazyImage = entry.target;
let classList = [].slice.call(lazyImage.classList);
//处理背景图片
if (classList.includes('lazy-background')) {
lazyImage.classList.add('visible');
lazyImageObserver.unobserve(lazyImage);
}
//处理图片
if (lazyImage.dataset.src) {
lazyImage.src = lazyImage.dataset.src;
lazyImage.classList.remove('lazy');
lazyImageObserver.unobserve(lazyImage);
}
}
});
});
lazyImageObserver = _lazyImageObserver;
}
export { lazyImageObserver };
step2: 懒加载实现
懒加载图片组件
/**
* params: 需要懒加载的图片元素;
* 原理: 给图片设置data-src="xxx" 当图片元素处于可视窗口时 将data-src赋值给src 实现图片的动态加载。
*/
import { lazyImageObserver } from 'initLazyImgObserver';
const lazyImg = (lazyImage) => {
if (lazyImageObserver) {
lazyImageObserver.observe(lazyImage);
} else {
if (lazyImage.dataset.src) {
lazyImage.src = lazyImage.dataset.src;
lazyImage.classList.remove('lazy');
}
}
};
export default lazyImg;
自定义hooks实现懒加载背景图
/****
*
* 背景图片懒加载
* 1.背景图片懒加载 给目标元素加一个.lazy-background类并将背景图片url通过.visible赋值
* 2.update:boolean————如果页面元素更新之后需要重新进行懒加载图片的收集,则需要传update参数
*/
import { useEffect } from 'react';
import { lazyImageObserver } from 'utils/initLazyImgObserver';
const collectLazyElement = () => {
var Backgrounds = [].slice.call(document.querySelectorAll('.lazy-background'));
if (lazyImageObserver) {
Backgrounds.forEach(function (lazyBgImage) {
lazyImageObserver.observe(lazyBgImage);
});
} else {
Backgrounds.forEach(function (lazyBgImage) {
const target = document.querySelector(lazyBgImage);
target.classList.add('visible');
});
}
};
export default (props) => {
const toUpdate = props?.update;
useEffect(() => {
collectLazyElement();
}, []);
useEffect(() => {
toUpdate && collectLazyElement();
}, [toUpdate]);
};
step3: 懒加载使用
图片懒加载使用——通过ref获取图片dom元素
import lazyImg from 'lazyImg';
const ScrollImg = (props) => {
const { src: imgSrc, alt = '', ...reset } = props;
const lazyImgRef = useRef();
useEffect(() => {
lazyImg(lazyImgRef.current);
}, [imgSrc]);
return <img ref={lazyImgRef} className="lazy" data-src={imgSrc} alt={alt} {...reset} />;
};
export default ScrollImg;
背景懒加载使用 ——通过给dom元素设置类名"lazy-background" 绑定需要观察的元素并给元素设置背景图,当该dom元素位于视口之外时不显示,位于视口时增加"visible"类 显示元素。
import useLazyBgImg from 'useLazyBgImg';
const BgLazy = () => {
useLazyBgImg();
return (
<div className="lazy-background" />
);
};
export default QuickStart;