baseframe-js
Version:
Baseframe JS is a comprehensive suite of modular plugins and utilities designed for front-end development
91 lines (90 loc) • 3.26 kB
JavaScript
import $be from "base-elem-js";
import { getDataOptions, setParams } from './util/helpers';
import Store from "./core/Store";
const VERSION = '2.0.1', DATA_NAME = 'LazyLoad', EVENT_NAME = 'lazyLoad', DEFAULTS = {
imgSrcName: 'src',
bgSrcName: 'bgSrc',
loadImgs: true,
inEvt: null,
outEvt: null,
force: false,
observerID: null,
unobserve: true,
observerOpts: { rootMargin: '48px' }
};
const lazyElemObservers = new Map();
export default class LazyLoad {
element;
params;
lazyElemObserver;
static defaults = DEFAULTS;
static version = VERSION;
static pluginName = DATA_NAME;
constructor(element, options) {
const s = this;
const dataOptions = getDataOptions(element, EVENT_NAME);
s.element = element;
s.lazyElemObserver;
s.params = setParams(LazyLoad.defaults, options, dataOptions);
s.#handleEvents();
return s;
}
static remove(element, plugin) {
$be(element).each((elem) => {
const s = plugin || Store(elem, DATA_NAME);
lazyElemObservers.delete(s.params.observerID);
s.lazyElemObserver.unobserve(elem);
Store(elem, DATA_NAME, null);
});
}
#handleImgOrBg(s, lazyElem) {
const { imgSrcName, bgSrcName } = s.params;
const src = lazyElem.dataset[imgSrcName];
const bgImg = lazyElem.dataset[bgSrcName];
if (lazyElem.loading === 'lazy') {
lazyElem.loading = 'eager';
}
if (src) {
lazyElem.src = src;
}
if (bgImg) {
lazyElem.style.backgroundImage = `url("${bgImg}")`;
lazyElem.removeAttribute('data-bg-src');
}
}
#handleEvents() {
const s = this;
const { observerID } = s.params;
if (observerID && !lazyElemObservers.has(observerID)) {
lazyElemObservers.set(observerID, s.#lazyElemObserverFactory());
s.lazyElemObserver = lazyElemObservers.get(observerID);
}
else {
s.lazyElemObserver = s.#lazyElemObserverFactory();
}
if (!observerID) {
console.warn(`Its recommended to set an 'observerID', so the element group can leverage the same one.`, s.element);
}
s.lazyElemObserver.observe(s.element);
}
#lazyElemObserverFactory() {
const s = this;
const { observerOpts } = s.params;
return new IntersectionObserver(function (entries) {
entries.forEach(function (entry) {
const { inEvt, outEvt, force, unobserve, loadImgs } = s.params;
const lazyElem = entry.target;
if (lazyElem instanceof HTMLElement) {
if (entry.isIntersecting && $be.isVisible(lazyElem) || force) {
loadImgs && s.#handleImgOrBg(s, lazyElem);
typeof inEvt === 'function' && inEvt(lazyElem, entry);
unobserve && s.lazyElemObserver.unobserve(lazyElem);
}
else {
typeof outEvt === 'function' && outEvt(lazyElem, entry);
}
}
});
}, observerOpts);
}
}