源码
export class LazyImage {
constructor(selector) {
this.lazyImages = Array.prototype.slice.call(document.querySelectorAll(selector));
this.init();
}
inViewShow() {
let len = this.lazyImages.length;
for (let i = 0; i < len; i++) {
let imageElement = this.lazyImages[i];
const rect = imageElement.getBoundingClientRect();
if (rect.top < document.documentElement.clientHeight) {
$(imageElement).attr('src', $(imageElement).attr('data-src'));
this.lazyImages.splice(i, 1);
len--;
i--;
if (this.lazyImages.length === 0) {
document.removeEventListener('scroll', this._throttleFn);
}
}
}
}
init() {
if ('IntersectionObserver' in window) {
let lazyImageObserver = new IntersectionObserver((entries, observer) => {
entries.forEach((entry, index) => {
if (entry.intersectionRatio && entry.intersectionRatio > 0) {
let lazyImage = entry.target;
lazyImage.src = lazyImage.dataset.src;
lazyImage.classList.remove('lazy-image');
lazyImageObserver.unobserve(lazyImage);
}
});
});
this.lazyImages.forEach(function (lazyImage) {
lazyImageObserver.observe(lazyImage);
});
} else {
this.inViewShow();
this._throttleFn = throttle(this.inViewShow.bind(this));
document.addEventListener('scroll', this._throttleFn);
}
}
}
export function throttle(fn, delay = 15, mustRun = 30) {
let t_start = null;
let timer = null;
let context = this;
return function () {
let t_current = +new Date();
let args = Array.prototype.slice.call(arguments);
clearTimeout(timer);
if (!t_start) {
t_start = t_current;
}
if (t_current - t_start > mustRun) {
fn.apply(context, args);
t_start = t_current;
} else {
timer = setTimeout(() => {
fn.apply(context, args);
}, delay);
}
};
}
使用方法
// index.HTML
<img
data-src="../static/images/index/index.jpg"
src="../static/images/common/loading.jpg"
class="lazy-image"
alt="首页图片"
/>
new LazyImage('.lazy-image')