实现图片懒加载
IntersectionObserver
demo https://codepen.io/liar0320/full/JjRVMOP
window.onload = () => {
var eles = document.querySelectorAll("img");
let loadInstance = loadImageInView({
loadingImg: "http://placekitten.com/100/100"
});
loadInstance(eles);
};
/** 加载试图内的图片
* @params { HtmlElement } eles
* @example <img data-src="xxx.jpg" />
*/
function loadImageInView({ errorImg, loadingImg } = {}) {
/**
* @param { "error" | "loading" } type
* @param { HTMLELEMENT } el
*/
function setDefaultImage(type, el) {
switch (type) {
case "error":
errorImg ? (el.src = errorImg) : console.error("加载图片失败");
break;
case "loading":
loadingImg ? (el.src = loadingImg) : console.info("请设置loading图片");
break;
default:
break;
}
}
function loadImg(url) {
let img = new Image();
img.src = url;
return new Promise((resolve, reject) => {
img.onload = () => {
resolve(img.src);
};
img.onerror = (e) => {
reject(e);
};
});
}
// 监听回调
var callback = (entries) => {
entries.forEach((item) => {
// 出现到可视区
if (item.intersectionRatio > 0) {
var ele = item.target;
var imgSrc = ele.getAttribute("data-src");
if (imgSrc) {
setDefaultImage("loading", ele);
// 预加载
loadImg(imgSrc)
.then((src) => {
ele.src = src;
})
.catch((err) => setDefaultImage("error", ele));
// 加载过清空路径,避免重复加载
ele.removeAttribute("data-src");
}
observer.unobserve(item.target);
}
});
// if (observer.takeRecords().length === 0) {
// observer.disconnect();
// observer = null;
// }
};
var observer = new IntersectionObserver(callback);
/** 加载试图内的图片
* @params { HtmlElement } eles
* @example <img data-src="xxx.jpg" />
*/
return function addEles(eles) {
// 列表元素加入监听
eles.forEach((item) => {
observer.observe(item);
});
return observer;
};
}