UNPKG

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
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); } }