unlazy
Version:
Universal lazy loading library for placeholder images leveraging native browser APIs
114 lines (113 loc) • 3.46 kB
JavaScript
const _ = "data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1 1'%3E%3C/svg%3E", S = typeof window > "u", b = !S && "loading" in HTMLImageElement.prototype, y = !S && (!("onscroll" in window) || /(?:gle|ing|ro)bot|crawl|spider/i.test(navigator.userAgent));
function h(e, t = document) {
return typeof e == "string" ? [...t.querySelectorAll(e)] : e instanceof Element ? [e] : [...e];
}
function g(e) {
const t = Date.now();
return _.replace(/\s/, ` data-id='${t}-${e}' `);
}
function m(e, t) {
let r;
return function(...n) {
r != null && clearTimeout(r), r = setTimeout(() => {
e(...n), r = void 0;
}, t);
};
}
function w(e = 'img[loading="lazy"]', {
hash: t = !0,
hashType: r = "blurhash",
placeholderSize: n = 32,
updateSizesOnResize: o = !1,
onImageLoad: a
} = {}) {
const c = /* @__PURE__ */ new Set();
for (const [l, s] of h(e).entries()) {
const E = u(s, { updateOnResize: o });
if (o && E && c.add(E), !s.dataset.src && !s.dataset.srcset) {
(typeof __UNLAZY_LOGGING__ > "u" || __UNLAZY_LOGGING__) && console.error("[unlazy] Missing `data-src` or `data-srcset` attribute", s);
continue;
}
if (y || !b) {
L(s), f(s), d(s);
continue;
}
if (s.src || (s.src = g(l)), s.complete && s.naturalWidth > 0) {
p(s, a);
continue;
}
const z = () => p(s, a);
s.addEventListener("load", z, { once: !0 }), c.add(
() => s.removeEventListener("load", z)
);
}
return () => {
for (const l of c) l();
c.clear();
};
}
function I(e = 'img[data-sizes="auto"], source[data-sizes="auto"]') {
for (const t of h(e))
u(t);
}
function p(e, t) {
if (A(e)) {
L(e), f(e), d(e), t?.(e);
return;
}
const r = new Image(), { srcset: n, src: o, sizes: a } = e.dataset;
if (a === "auto") {
const c = v(e);
c && (r.sizes = `${c}px`);
} else e.sizes && (r.sizes = e.sizes);
n && (r.srcset = n), o && (r.src = o), r.addEventListener("load", () => {
f(e), d(e), t?.(e);
}, { once: !0 });
}
const i = /* @__PURE__ */ new WeakMap();
function u(e, t) {
if (e.dataset.sizes !== "auto")
return;
const r = v(e);
if (r && (e.sizes = `${r}px`), A(e) && t?.processSourceElements)
for (const n of [...e.parentElement.getElementsByTagName("source")])
u(n, { processSourceElements: !0 });
if (t?.updateOnResize) {
if (!i.has(e)) {
const n = m(() => u(e), 500), o = new ResizeObserver(n);
i.set(e, o), o.observe(e);
}
return () => {
const n = i.get(e);
n && (n.disconnect(), i.delete(e));
};
}
}
function d(e) {
e.dataset.src && (e.src = e.dataset.src, e.removeAttribute("data-src"));
}
function f(e) {
e.dataset.srcset && (e.srcset = e.dataset.srcset, e.removeAttribute("data-srcset"));
}
function L(e) {
const t = e.parentElement;
t?.tagName.toLowerCase() === "picture" && ([...t.querySelectorAll("source[data-srcset]")].forEach(f), [...t.querySelectorAll("source[data-src]")].forEach(d));
}
function v(e) {
return e instanceof HTMLSourceElement ? e.parentElement?.getElementsByTagName("img")[0]?.offsetWidth : e.offsetWidth;
}
function A(e) {
return e.parentElement?.tagName.toLowerCase() === "picture";
}
const O = Object.freeze({
autoSizes: I,
lazyLoad: w,
loadImage: p
});
document.currentScript?.hasAttribute("init") && w();
export {
I as autoSizes,
O as default,
w as lazyLoad,
p as loadImage
};