目的
界面优化,由于图片数量过多,一次性加载完比较耗时,故采用懒加载。
原理
- 为了减少图片请求,初始时,将所有的img标签src设置为同一小型图片,这样只有一次请求
- 将图片的真实路径绑定在其他属性上如data-url="xxx"
<img data-url="xxx" src="1px.gif" width="100" height="100"/>
- 判断滚动事件,当图片进入视野,再替换src的属性值,进行图片加载。
实现
const lazyImg = (height) => {
var imgs = document.getElementsByTagName("img");
// 初始化先执行一次
scrollFn();
// 监听滚动事件
window.addEventListener("scroll", scrollFn);
function scrollFn() {
var clietH =
window.innerHeight ||
document.documentElement.clientHeight ||
document.body.clientHeight;
var scrollTop =
document.documentElement.scrollTop ||
window.pageYOffset ||
document.body.scrollTop;
Array.from(imgs).forEach((item) => {
let eleTop = item.offsetTop;
let count = eleTop - (scrollTop + clietH);
if (count < height) {
//从data-url中取出真实的图片地址赋值给scr
item.setAttribute(
"src",
item.getAttribute("data-url")
);
}
});
}
return () => {
// 移除监听事件
window.removeEventListener("scroll", scrollFn);
};
};
const removeLazyImg = lazyImg(100);
使用getBoundingClientRect方法实现:
const lazyImg = (height) => {
var imgs = document.getElementsByTagName("img");
// 初始化先执行一次
scrollFn();
// 监听滚动事件
window.addEventListener("scroll", scrollFn);
function scrollFn() {
var clietH =
window.innerHeight ||
document.documentElement.clientHeight ||
document.body.clientHeight;
Array.from(imgs).forEach((item) => {
let ele = item.getBoundingClientRect();
ele.top >= 0 &&
ele.top <= clietH + height &&
item.setAttribute(
"src",
item.getAttribute("data-url")
);
});
}
return () => {
// 移除监听事件
window.removeEventListener("scroll", scrollFn);
};
};
const removeLazyImg = lazyImg(-100);
使用IntersectionObserver实现:
const lazyImg = (height) => {
var imgs = document.getElementsByTagName("img");
let io = new IntersectionObserver((entires) => {
entires.forEach((item) => {
// 图片元素
let ele = item.target;
if (
item.intersectionRatio > 0 &&
item.intersectionRatio <= 1
) {
ele.setAttribute(
"src",
ele.getAttribute("data-url")
);
}
});
});
// 给每所有图片都添加进观察器
Array.from(imgs).forEach((element) => {
io.observe(element);
});
};
lazyImg(-100);