@tjoskar/react-lazyload-img
Version:
Lazy image loader for react
80 lines • 2.69 kB
JavaScript
const defaultObserverOptions = {
root: undefined,
rootMargin: undefined,
threshold: undefined
};
const observerKeys = [];
const observers = new WeakMap();
const images = new WeakMap();
export const call = fn => fn && fn();
export const isNull = (obj) => obj === null;
const createIntersectionObserver = (options) => new IntersectionObserver(loadingCallback, options);
function loadingCallback(entrys) {
entrys.filter(entry => entry.isIntersecting).forEach(entry => {
const target = entry.target;
const metaData = images.get(target);
if (!metaData) {
console.warn('Could not find meta data for image');
return;
}
metaData.observer.unobserve(target);
loadImage(metaData.options.image)
.catch(() => {
if (metaData.options.errorImage) {
return loadImage(metaData.options.errorImage);
}
return Promise.resolve(metaData.options.defaultImage);
})
.catch(() => metaData.options.defaultImage)
.then((imagePath) => {
setImage(target, imagePath);
addCssClassName(target, 'lazy-loaded');
call(metaData.options.onLoaded);
});
});
}
export function setImage(element, imagePath) {
if (isImageElement(element)) {
element.src = imagePath;
}
else {
element.style.backgroundImage = `url('${imagePath}')`;
}
}
export function loadImage(imagePath) {
return new Promise((resolve, reject) => {
const img = new Image();
img.src = imagePath;
img.onload = () => resolve(imagePath);
img.onerror = err => reject(err);
});
}
export function isImageElement(element) {
return element.nodeName.toLowerCase() === 'img';
}
export function addCssClassName(element, cssClassName) {
if (!element.className.includes(cssClassName)) {
element.className += ` ${cssClassName}`;
}
}
export function registerImageToLazyLoad(element, metadata) {
const options = metadata.options || defaultObserverOptions;
let observerKey = observerKeys.find(oKey => oKey.root === options.root &&
oKey.rootMargin === options.rootMargin &&
oKey.threshold === options.threshold);
if (!observerKey) {
observerKey = options;
observerKeys.push(observerKey);
}
let observer = observers.get(observerKey);
if (!observer) {
observer = createIntersectionObserver(observerKey);
observers.set(observerKey, observer);
}
images.set(element, {
observer,
options: metadata
});
observer.observe(element);
}
//# sourceMappingURL=lazyload.js.map