From ae415e6fa7347acad2bb0db4f3f47e80aa39e82c Mon Sep 17 00:00:00 2001 From: Andrea Verlicchi Date: Wed, 3 Apr 2024 14:25:12 +0200 Subject: [PATCH] Releasing 19.1.2 --- CHANGELOG.md | 4 + README.md | 8 +- dist/lazyload.iife.js | 451 +++++++++++++++++--------------------- dist/lazyload.iife.min.js | 2 +- dist/lazyload.js | 451 +++++++++++++++++--------------------- dist/lazyload.min.js | 2 +- package-lock.json | 4 +- package.json | 2 +- 8 files changed, 411 insertions(+), 513 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fbc6c56..55d753f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Version 19 +#### 19.1.2 + +- Modernized code and smaller file bundles, everything is now shipped as in the ES2015 format. + #### 19.1.1 - Removed code to support image-set on legacy versions of Chromium browsers diff --git a/README.md b/README.md index ebd1571..5aaa19f 100644 --- a/README.md +++ b/README.md @@ -176,7 +176,7 @@ Please note that the video poster can be lazily loaded too. ## 👩‍💻 Getting started - Script -The latest, recommended version of LazyLoad is **19.1.1**. +The latest, recommended version of LazyLoad is **19.1.2**. Note that if you need to support Internet Explorer 11, you need to use version 17.9.0 or below. Quickly understand how to upgrade from a previous version reading the [practical upgrade guide](UPGRADE.md). @@ -186,7 +186,7 @@ Quickly understand how to upgrade from a previous version reading the [practical The easiest way to use LazyLoad is to include the script from a CDN. ```html - + ``` OR, if you prefer to import it as an ES module: @@ -237,7 +237,7 @@ Then include the script. ```html ``` @@ -271,7 +271,7 @@ Then include the script. ```html ``` diff --git a/dist/lazyload.iife.js b/dist/lazyload.iife.js index d08e397..21d9435 100644 --- a/dist/lazyload.iife.js +++ b/dist/lazyload.iife.js @@ -1,11 +1,11 @@ var LazyLoad = (function () { 'use strict'; - var runningOnBrowser = typeof window !== "undefined"; - var isBot = runningOnBrowser && !("onscroll" in window) || typeof navigator !== "undefined" && /(gle|ing|ro)bot|crawl|spider/i.test(navigator.userAgent); - var isHiDpi = runningOnBrowser && window.devicePixelRatio > 1; + const runningOnBrowser = typeof window !== "undefined"; + const isBot = runningOnBrowser && !("onscroll" in window) || typeof navigator !== "undefined" && /(gle|ing|ro)bot|crawl|spider/i.test(navigator.userAgent); + const isHiDpi = runningOnBrowser && window.devicePixelRatio > 1; - var defaultSettings = { + const defaultSettings = { elements_selector: ".lazy", container: isBot || runningOnBrowser ? document : null, threshold: 300, @@ -39,27 +39,27 @@ var LazyLoad = (function () { use_native: false, restore_on_error: false }; - var getExtendedSettings = function getExtendedSettings(customSettings) { + const getExtendedSettings = customSettings => { return Object.assign({}, defaultSettings, customSettings); }; /* Creates instance and notifies it through the window element */ - var createInstance = function createInstance(classObj, options) { - var event; - var eventString = "LazyLoad::Initialized"; - var instance = new classObj(options); + const createInstance = function (classObj, options) { + let event; + const eventString = "LazyLoad::Initialized"; + const instance = new classObj(options); try { // Works in modern browsers event = new CustomEvent(eventString, { detail: { - instance: instance + instance } }); } catch (err) { // Works in Internet Explorer (all versions) event = document.createEvent("CustomEvent"); event.initCustomEvent(eventString, false, false, { - instance: instance + instance }); } window.dispatchEvent(event); @@ -67,7 +67,7 @@ var LazyLoad = (function () { /* Auto initialization of one or more instances of LazyLoad, depending on the options passed in (plain object or an array) */ - var autoInitialize = function autoInitialize(classObj, options) { + const autoInitialize = (classObj, options) => { if (!options) { return; } @@ -76,66 +76,50 @@ var LazyLoad = (function () { createInstance(classObj, options); } else { // Array of objects - for (var i = 0, optionsItem; optionsItem = options[i]; i += 1) { + for (let i = 0, optionsItem; optionsItem = options[i]; i += 1) { createInstance(classObj, optionsItem); } } }; - var SRC = "src"; - var SRCSET = "srcset"; - var SIZES = "sizes"; - var POSTER = "poster"; - var ORIGINALS = "llOriginalAttrs"; - var DATA = "data"; + const SRC = "src"; + const SRCSET = "srcset"; + const SIZES = "sizes"; + const POSTER = "poster"; + const ORIGINALS = "llOriginalAttrs"; + const DATA = "data"; - var statusLoading = "loading"; - var statusLoaded = "loaded"; - var statusApplied = "applied"; - var statusEntered = "entered"; - var statusError = "error"; - var statusNative = "native"; + const statusLoading = "loading"; + const statusLoaded = "loaded"; + const statusApplied = "applied"; + const statusEntered = "entered"; + const statusError = "error"; + const statusNative = "native"; - var dataPrefix = "data-"; - var statusDataName = "ll-status"; - var getData = function getData(element, attribute) { + const dataPrefix = "data-"; + const statusDataName = "ll-status"; + const getData = (element, attribute) => { return element.getAttribute(dataPrefix + attribute); }; - var setData = function setData(element, attribute, value) { - var attrName = dataPrefix + attribute; + const setData = (element, attribute, value) => { + const attrName = dataPrefix + attribute; if (value === null) { element.removeAttribute(attrName); return; } element.setAttribute(attrName, value); }; - var getStatus = function getStatus(element) { - return getData(element, statusDataName); - }; - var setStatus = function setStatus(element, status) { - return setData(element, statusDataName, status); - }; - var resetStatus = function resetStatus(element) { - return setStatus(element, null); - }; - var hasEmptyStatus = function hasEmptyStatus(element) { - return getStatus(element) === null; - }; - var hasStatusLoading = function hasStatusLoading(element) { - return getStatus(element) === statusLoading; - }; - var hasStatusError = function hasStatusError(element) { - return getStatus(element) === statusError; - }; - var hasStatusNative = function hasStatusNative(element) { - return getStatus(element) === statusNative; - }; - var statusesAfterLoading = [statusLoading, statusLoaded, statusApplied, statusError]; - var hadStartedLoading = function hadStartedLoading(element) { - return statusesAfterLoading.indexOf(getStatus(element)) >= 0; - }; - - var safeCallback = function safeCallback(callback, arg1, arg2, arg3) { + const getStatus = element => getData(element, statusDataName); + const setStatus = (element, status) => setData(element, statusDataName, status); + const resetStatus = element => setStatus(element, null); + const hasEmptyStatus = element => getStatus(element) === null; + const hasStatusLoading = element => getStatus(element) === statusLoading; + const hasStatusError = element => getStatus(element) === statusError; + const hasStatusNative = element => getStatus(element) === statusNative; + const statusesAfterLoading = [statusLoading, statusLoaded, statusApplied, statusError]; + const hadStartedLoading = element => statusesAfterLoading.indexOf(getStatus(element)) >= 0; + + const safeCallback = (callback, arg1, arg2, arg3) => { if (!callback || typeof callback !== 'function') { return; } @@ -150,7 +134,7 @@ var LazyLoad = (function () { callback(arg1); }; - var addClass = function addClass(element, className) { + const addClass = (element, className) => { if (!runningOnBrowser) { return; } @@ -159,7 +143,7 @@ var LazyLoad = (function () { } element.classList.add(className); }; - var removeClass = function removeClass(element, className) { + const removeClass = (element, className) => { if (!runningOnBrowser) { return; } @@ -169,97 +153,85 @@ var LazyLoad = (function () { element.classList.remove(className); }; - var addTempImage = function addTempImage(element) { + const addTempImage = element => { element.llTempImage = document.createElement("IMG"); }; - var deleteTempImage = function deleteTempImage(element) { + const deleteTempImage = element => { delete element.llTempImage; }; - var getTempImage = function getTempImage(element) { - return element.llTempImage; - }; + const getTempImage = element => element.llTempImage; - var unobserve = function unobserve(element, instance) { + const unobserve = (element, instance) => { if (!instance) return; - var observer = instance._observer; + const observer = instance._observer; if (!observer) return; observer.unobserve(element); }; - var resetObserver = function resetObserver(observer) { + const resetObserver = observer => { observer.disconnect(); }; - var unobserveEntered = function unobserveEntered(element, settings, instance) { + const unobserveEntered = (element, settings, instance) => { if (settings.unobserve_entered) unobserve(element, instance); }; - var updateLoadingCount = function updateLoadingCount(instance, delta) { + const updateLoadingCount = (instance, delta) => { if (!instance) return; instance.loadingCount += delta; }; - var decreaseToLoadCount = function decreaseToLoadCount(instance) { + const decreaseToLoadCount = instance => { if (!instance) return; instance.toLoadCount -= 1; }; - var setToLoadCount = function setToLoadCount(instance, value) { + const setToLoadCount = (instance, value) => { if (!instance) return; instance.toLoadCount = value; }; - var isSomethingLoading = function isSomethingLoading(instance) { - return instance.loadingCount > 0; - }; - var haveElementsToLoad = function haveElementsToLoad(instance) { - return instance.toLoadCount > 0; - }; + const isSomethingLoading = instance => instance.loadingCount > 0; + const haveElementsToLoad = instance => instance.toLoadCount > 0; - var getSourceTags = function getSourceTags(parentTag) { - var sourceTags = []; - for (var i = 0, childTag; childTag = parentTag.children[i]; i += 1) { + const getSourceTags = parentTag => { + let sourceTags = []; + for (let i = 0, childTag; childTag = parentTag.children[i]; i += 1) { if (childTag.tagName === "SOURCE") { sourceTags.push(childTag); } } return sourceTags; }; - var forEachPictureSource = function forEachPictureSource(element, fn) { - var parent = element.parentNode; + const forEachPictureSource = (element, fn) => { + const parent = element.parentNode; if (!parent || parent.tagName !== "PICTURE") { return; } - var sourceTags = getSourceTags(parent); + let sourceTags = getSourceTags(parent); sourceTags.forEach(fn); }; - var forEachVideoSource = function forEachVideoSource(element, fn) { - var sourceTags = getSourceTags(element); + const forEachVideoSource = (element, fn) => { + let sourceTags = getSourceTags(element); sourceTags.forEach(fn); }; - var attrsSrc = [SRC]; - var attrsSrcPoster = [SRC, POSTER]; - var attrsSrcSrcsetSizes = [SRC, SRCSET, SIZES]; - var attrsData = [DATA]; - var hasOriginalAttrs = function hasOriginalAttrs(element) { - return !!element[ORIGINALS]; - }; - var getOriginalAttrs = function getOriginalAttrs(element) { - return element[ORIGINALS]; - }; - var deleteOriginalAttrs = function deleteOriginalAttrs(element) { - return delete element[ORIGINALS]; - }; + const attrsSrc = [SRC]; + const attrsSrcPoster = [SRC, POSTER]; + const attrsSrcSrcsetSizes = [SRC, SRCSET, SIZES]; + const attrsData = [DATA]; + const hasOriginalAttrs = element => !!element[ORIGINALS]; + const getOriginalAttrs = element => element[ORIGINALS]; + const deleteOriginalAttrs = element => delete element[ORIGINALS]; // ## SAVE ## - var setOriginalsObject = function setOriginalsObject(element, attributes) { + const setOriginalsObject = (element, attributes) => { if (hasOriginalAttrs(element)) { return; } - var originals = {}; - attributes.forEach(function (attribute) { + const originals = {}; + attributes.forEach(attribute => { originals[attribute] = element.getAttribute(attribute); }); element[ORIGINALS] = originals; }; - var saveOriginalBackgroundStyle = function saveOriginalBackgroundStyle(element) { + const saveOriginalBackgroundStyle = element => { if (hasOriginalAttrs(element)) { return; } @@ -270,31 +242,31 @@ var LazyLoad = (function () { // ## RESTORE ## - var setOrResetAttribute = function setOrResetAttribute(element, attrName, value) { + const setOrResetAttribute = (element, attrName, value) => { if (!value) { element.removeAttribute(attrName); return; } element.setAttribute(attrName, value); }; - var restoreOriginalAttrs = function restoreOriginalAttrs(element, attributes) { + const restoreOriginalAttrs = (element, attributes) => { if (!hasOriginalAttrs(element)) { return; } - var originals = getOriginalAttrs(element); - attributes.forEach(function (attribute) { + const originals = getOriginalAttrs(element); + attributes.forEach(attribute => { setOrResetAttribute(element, attribute, originals[attribute]); }); }; - var restoreOriginalBgImage = function restoreOriginalBgImage(element) { + const restoreOriginalBgImage = element => { if (!hasOriginalAttrs(element)) { return; } - var originals = getOriginalAttrs(element); + const originals = getOriginalAttrs(element); element.style.backgroundImage = originals.backgroundImage; }; - var manageApplied = function manageApplied(element, settings, instance) { + const manageApplied = (element, settings, instance) => { addClass(element, settings.class_applied); setStatus(element, statusApplied); // Instance is not provided when loading is called from static class @@ -305,7 +277,7 @@ var LazyLoad = (function () { } safeCallback(settings.callback_applied, element, instance); }; - var manageLoading = function manageLoading(element, settings, instance) { + const manageLoading = (element, settings, instance) => { addClass(element, settings.class_loading); setStatus(element, statusLoading); // Instance is not provided when loading is called from static class @@ -313,31 +285,31 @@ var LazyLoad = (function () { updateLoadingCount(instance, +1); safeCallback(settings.callback_loading, element, instance); }; - var setAttributeIfValue = function setAttributeIfValue(element, attrName, value) { + const setAttributeIfValue = (element, attrName, value) => { if (!value) { return; } element.setAttribute(attrName, value); }; - var setImageAttributes = function setImageAttributes(element, settings) { + const setImageAttributes = (element, settings) => { setAttributeIfValue(element, SIZES, getData(element, settings.data_sizes)); setAttributeIfValue(element, SRCSET, getData(element, settings.data_srcset)); setAttributeIfValue(element, SRC, getData(element, settings.data_src)); }; - var setSourcesImg = function setSourcesImg(imgEl, settings) { - forEachPictureSource(imgEl, function (sourceTag) { + const setSourcesImg = (imgEl, settings) => { + forEachPictureSource(imgEl, sourceTag => { setOriginalsObject(sourceTag, attrsSrcSrcsetSizes); setImageAttributes(sourceTag, settings); }); setOriginalsObject(imgEl, attrsSrcSrcsetSizes); setImageAttributes(imgEl, settings); }; - var setSourcesIframe = function setSourcesIframe(iframe, settings) { + const setSourcesIframe = (iframe, settings) => { setOriginalsObject(iframe, attrsSrc); setAttributeIfValue(iframe, SRC, getData(iframe, settings.data_src)); }; - var setSourcesVideo = function setSourcesVideo(videoEl, settings) { - forEachVideoSource(videoEl, function (sourceEl) { + const setSourcesVideo = (videoEl, settings) => { + forEachVideoSource(videoEl, sourceEl => { setOriginalsObject(sourceEl, attrsSrc); setAttributeIfValue(sourceEl, SRC, getData(sourceEl, settings.data_src)); }); @@ -346,16 +318,16 @@ var LazyLoad = (function () { setAttributeIfValue(videoEl, SRC, getData(videoEl, settings.data_src)); videoEl.load(); }; - var setSourcesObject = function setSourcesObject(object, settings) { + const setSourcesObject = (object, settings) => { setOriginalsObject(object, attrsData); setAttributeIfValue(object, DATA, getData(object, settings.data_src)); }; - var setBackground = function setBackground(element, settings, instance) { - var bg1xValue = getData(element, settings.data_bg); - var bgHiDpiValue = getData(element, settings.data_bg_hidpi); - var bgDataValue = isHiDpi && bgHiDpiValue ? bgHiDpiValue : bg1xValue; + const setBackground = (element, settings, instance) => { + const bg1xValue = getData(element, settings.data_bg); + const bgHiDpiValue = getData(element, settings.data_bg_hidpi); + const bgDataValue = isHiDpi && bgHiDpiValue ? bgHiDpiValue : bg1xValue; if (!bgDataValue) return; - element.style.backgroundImage = "url(\"".concat(bgDataValue, "\")"); + element.style.backgroundImage = `url("${bgDataValue}")`; getTempImage(element).setAttribute(SRC, bgDataValue); manageLoading(element, settings, instance); }; @@ -363,43 +335,41 @@ var LazyLoad = (function () { // NOTE: THE TEMP IMAGE TRICK CANNOT BE DONE WITH data-multi-bg // BECAUSE INSIDE ITS VALUES MUST BE WRAPPED WITH URL() AND ONE OF THEM // COULD BE A GRADIENT BACKGROUND IMAGE - var setMultiBackground = function setMultiBackground(element, settings, instance) { - var bg1xValue = getData(element, settings.data_bg_multi); - var bgHiDpiValue = getData(element, settings.data_bg_multi_hidpi); - var bgDataValue = isHiDpi && bgHiDpiValue ? bgHiDpiValue : bg1xValue; + const setMultiBackground = (element, settings, instance) => { + const bg1xValue = getData(element, settings.data_bg_multi); + const bgHiDpiValue = getData(element, settings.data_bg_multi_hidpi); + const bgDataValue = isHiDpi && bgHiDpiValue ? bgHiDpiValue : bg1xValue; if (!bgDataValue) { return; } element.style.backgroundImage = bgDataValue; manageApplied(element, settings, instance); }; - var setImgsetBackground = function setImgsetBackground(element, settings, instance) { - var bgImgSetDataValue = getData(element, settings.data_bg_set); + const setImgsetBackground = (element, settings, instance) => { + const bgImgSetDataValue = getData(element, settings.data_bg_set); if (!bgImgSetDataValue) { return; } - var imgSetValues = bgImgSetDataValue.split("|"); - var bgImageValues = imgSetValues.map(function (value) { - return "image-set(".concat(value, ")"); - }); + const imgSetValues = bgImgSetDataValue.split("|"); + let bgImageValues = imgSetValues.map(value => `image-set(${value})`); element.style.backgroundImage = bgImageValues.join(); manageApplied(element, settings, instance); }; - var setSourcesFunctions = { + const setSourcesFunctions = { IMG: setSourcesImg, IFRAME: setSourcesIframe, VIDEO: setSourcesVideo, OBJECT: setSourcesObject }; - var setSourcesNative = function setSourcesNative(element, settings) { - var setSourcesFunction = setSourcesFunctions[element.tagName]; + const setSourcesNative = (element, settings) => { + const setSourcesFunction = setSourcesFunctions[element.tagName]; if (!setSourcesFunction) { return; } setSourcesFunction(element, settings); }; - var setSources = function setSources(element, settings, instance) { - var setSourcesFunction = setSourcesFunctions[element.tagName]; + const setSources = (element, settings, instance) => { + const setSourcesFunction = setSourcesFunctions[element.tagName]; if (!setSourcesFunction) { return; } @@ -407,43 +377,41 @@ var LazyLoad = (function () { manageLoading(element, settings, instance); }; - var elementsWithLoadEvent = ["IMG", "IFRAME", "VIDEO", "OBJECT"]; - var hasLoadEvent = function hasLoadEvent(element) { - return elementsWithLoadEvent.indexOf(element.tagName) > -1; - }; - var checkFinish = function checkFinish(settings, instance) { + const elementsWithLoadEvent = ["IMG", "IFRAME", "VIDEO", "OBJECT"]; + const hasLoadEvent = element => elementsWithLoadEvent.indexOf(element.tagName) > -1; + const checkFinish = (settings, instance) => { if (instance && !isSomethingLoading(instance) && !haveElementsToLoad(instance)) { safeCallback(settings.callback_finish, instance); } }; - var addEventListener = function addEventListener(element, eventName, handler) { + const addEventListener = (element, eventName, handler) => { element.addEventListener(eventName, handler); element.llEvLisnrs[eventName] = handler; }; - var removeEventListener = function removeEventListener(element, eventName, handler) { + const removeEventListener = (element, eventName, handler) => { element.removeEventListener(eventName, handler); }; - var hasEventListeners = function hasEventListeners(element) { + const hasEventListeners = element => { return !!element.llEvLisnrs; }; - var addEventListeners = function addEventListeners(element, loadHandler, errorHandler) { + const addEventListeners = (element, loadHandler, errorHandler) => { if (!hasEventListeners(element)) element.llEvLisnrs = {}; - var loadEventName = element.tagName === "VIDEO" ? "loadeddata" : "load"; + const loadEventName = element.tagName === "VIDEO" ? "loadeddata" : "load"; addEventListener(element, loadEventName, loadHandler); addEventListener(element, "error", errorHandler); }; - var removeEventListeners = function removeEventListeners(element) { + const removeEventListeners = element => { if (!hasEventListeners(element)) { return; } - var eventListeners = element.llEvLisnrs; - for (var eventName in eventListeners) { - var handler = eventListeners[eventName]; + const eventListeners = element.llEvLisnrs; + for (let eventName in eventListeners) { + const handler = eventListeners[eventName]; removeEventListener(element, eventName, handler); } delete element.llEvLisnrs; }; - var doneHandler = function doneHandler(element, settings, instance) { + const doneHandler = (element, settings, instance) => { deleteTempImage(element); updateLoadingCount(instance, -1); decreaseToLoadCount(instance); @@ -452,16 +420,16 @@ var LazyLoad = (function () { unobserve(element, instance); } }; - var loadHandler = function loadHandler(event, element, settings, instance) { - var goingNative = hasStatusNative(element); + const loadHandler = (event, element, settings, instance) => { + const goingNative = hasStatusNative(element); doneHandler(element, settings, instance); addClass(element, settings.class_loaded); setStatus(element, statusLoaded); safeCallback(settings.callback_loaded, element, instance); if (!goingNative) checkFinish(settings, instance); }; - var errorHandler = function errorHandler(event, element, settings, instance) { - var goingNative = hasStatusNative(element); + const errorHandler = (event, element, settings, instance) => { + const goingNative = hasStatusNative(element); doneHandler(element, settings, instance); addClass(element, settings.class_error); setStatus(element, statusError); @@ -469,24 +437,24 @@ var LazyLoad = (function () { if (settings.restore_on_error) restoreOriginalAttrs(element, attrsSrcSrcsetSizes); if (!goingNative) checkFinish(settings, instance); }; - var addOneShotEventListeners = function addOneShotEventListeners(element, settings, instance) { - var elementToListenTo = getTempImage(element) || element; + const addOneShotEventListeners = (element, settings, instance) => { + const elementToListenTo = getTempImage(element) || element; if (hasEventListeners(elementToListenTo)) { // This happens when loading is retried twice return; } - var _loadHandler = function _loadHandler(event) { + const _loadHandler = event => { loadHandler(event, element, settings, instance); removeEventListeners(elementToListenTo); }; - var _errorHandler = function _errorHandler(event) { + const _errorHandler = event => { errorHandler(event, element, settings, instance); removeEventListeners(elementToListenTo); }; addEventListeners(elementToListenTo, _loadHandler, _errorHandler); }; - var loadBackground = function loadBackground(element, settings, instance) { + const loadBackground = (element, settings, instance) => { addTempImage(element); addOneShotEventListeners(element, settings, instance); saveOriginalBackgroundStyle(element); @@ -494,70 +462,70 @@ var LazyLoad = (function () { setMultiBackground(element, settings, instance); setImgsetBackground(element, settings, instance); }; - var loadRegular = function loadRegular(element, settings, instance) { + const loadRegular = (element, settings, instance) => { addOneShotEventListeners(element, settings, instance); setSources(element, settings, instance); }; - var load = function load(element, settings, instance) { + const load = (element, settings, instance) => { if (hasLoadEvent(element)) { loadRegular(element, settings, instance); } else { loadBackground(element, settings, instance); } }; - var loadNative = function loadNative(element, settings, instance) { + const loadNative = (element, settings, instance) => { element.setAttribute("loading", "lazy"); addOneShotEventListeners(element, settings, instance); setSourcesNative(element, settings); setStatus(element, statusNative); }; - var removeImageAttributes = function removeImageAttributes(element) { + const removeImageAttributes = element => { element.removeAttribute(SRC); element.removeAttribute(SRCSET); element.removeAttribute(SIZES); }; - var resetSourcesImg = function resetSourcesImg(element) { - forEachPictureSource(element, function (sourceTag) { + const resetSourcesImg = element => { + forEachPictureSource(element, sourceTag => { removeImageAttributes(sourceTag); }); removeImageAttributes(element); }; - var restoreImg = function restoreImg(imgEl) { - forEachPictureSource(imgEl, function (sourceEl) { + const restoreImg = imgEl => { + forEachPictureSource(imgEl, sourceEl => { restoreOriginalAttrs(sourceEl, attrsSrcSrcsetSizes); }); restoreOriginalAttrs(imgEl, attrsSrcSrcsetSizes); }; - var restoreVideo = function restoreVideo(videoEl) { - forEachVideoSource(videoEl, function (sourceEl) { + const restoreVideo = videoEl => { + forEachVideoSource(videoEl, sourceEl => { restoreOriginalAttrs(sourceEl, attrsSrc); }); restoreOriginalAttrs(videoEl, attrsSrcPoster); videoEl.load(); }; - var restoreIframe = function restoreIframe(iframeEl) { + const restoreIframe = iframeEl => { restoreOriginalAttrs(iframeEl, attrsSrc); }; - var restoreObject = function restoreObject(objectEl) { + const restoreObject = objectEl => { restoreOriginalAttrs(objectEl, attrsData); }; - var restoreFunctions = { + const restoreFunctions = { IMG: restoreImg, IFRAME: restoreIframe, VIDEO: restoreVideo, OBJECT: restoreObject }; - var restoreAttributes = function restoreAttributes(element) { - var restoreFunction = restoreFunctions[element.tagName]; + const restoreAttributes = element => { + const restoreFunction = restoreFunctions[element.tagName]; if (!restoreFunction) { restoreOriginalBgImage(element); return; } restoreFunction(element); }; - var resetClasses = function resetClasses(element, settings) { + const resetClasses = (element, settings) => { if (hasEmptyStatus(element) || hasStatusNative(element)) { return; } @@ -568,14 +536,14 @@ var LazyLoad = (function () { removeClass(element, settings.class_loaded); removeClass(element, settings.class_error); }; - var restore = function restore(element, settings) { + const restore = (element, settings) => { restoreAttributes(element); resetClasses(element, settings); resetStatus(element); deleteOriginalAttrs(element); }; - var cancelLoading = function cancelLoading(element, entry, settings, instance) { + const cancelLoading = (element, entry, settings, instance) => { if (!settings.cancel_on_exit) return; if (!hasStatusLoading(element)) return; if (element.tagName !== "IMG") return; //Works only on images @@ -588,9 +556,9 @@ var LazyLoad = (function () { safeCallback(settings.callback_cancel, element, entry, instance); }; - var onEnter = function onEnter(element, entry, settings, instance) { - var dontLoad = hadStartedLoading(element); /* Save status - before setting it, to prevent loading it again. Fixes #526. */ + const onEnter = (element, entry, settings, instance) => { + const dontLoad = hadStartedLoading(element); /* Save status + before setting it, to prevent loading it again. Fixes #526. */ setStatus(element, statusEntered); addClass(element, settings.class_entered); removeClass(element, settings.class_exited); @@ -599,19 +567,17 @@ var LazyLoad = (function () { if (dontLoad) return; load(element, settings, instance); }; - var onExit = function onExit(element, entry, settings, instance) { + const onExit = (element, entry, settings, instance) => { if (hasEmptyStatus(element)) return; //Ignore the first pass, at landing addClass(element, settings.class_exited); cancelLoading(element, entry, settings, instance); safeCallback(settings.callback_exit, element, entry, instance); }; - var tagsWithNativeLazy = ["IMG", "IFRAME", "VIDEO"]; - var shouldUseNative = function shouldUseNative(settings) { - return settings.use_native && "loading" in HTMLImageElement.prototype; - }; - var loadAllNative = function loadAllNative(elements, settings, instance) { - elements.forEach(function (element) { + const tagsWithNativeLazy = ["IMG", "IFRAME", "VIDEO"]; + const shouldUseNative = settings => settings.use_native && "loading" in HTMLImageElement.prototype; + const loadAllNative = (elements, settings, instance) => { + elements.forEach(element => { if (tagsWithNativeLazy.indexOf(element.tagName) === -1) { return; } @@ -620,83 +586,65 @@ var LazyLoad = (function () { setToLoadCount(instance, 0); }; - var isIntersecting = function isIntersecting(entry) { - return entry.isIntersecting || entry.intersectionRatio > 0; - }; - var getObserverSettings = function getObserverSettings(settings) { - return { - root: settings.container === document ? null : settings.container, - rootMargin: settings.thresholds || settings.threshold + "px" - }; - }; - var intersectionHandler = function intersectionHandler(entries, settings, instance) { - entries.forEach(function (entry) { - return isIntersecting(entry) ? onEnter(entry.target, entry, settings, instance) : onExit(entry.target, entry, settings, instance); - }); + const isIntersecting = entry => entry.isIntersecting || entry.intersectionRatio > 0; + const getObserverSettings = settings => ({ + root: settings.container === document ? null : settings.container, + rootMargin: settings.thresholds || settings.threshold + "px" + }); + const intersectionHandler = (entries, settings, instance) => { + entries.forEach(entry => isIntersecting(entry) ? onEnter(entry.target, entry, settings, instance) : onExit(entry.target, entry, settings, instance)); }; - var observeElements = function observeElements(observer, elements) { - elements.forEach(function (element) { + const observeElements = (observer, elements) => { + elements.forEach(element => { observer.observe(element); }); }; - var updateObserver = function updateObserver(observer, elementsToObserve) { + const updateObserver = (observer, elementsToObserve) => { resetObserver(observer); observeElements(observer, elementsToObserve); }; - var setObserver = function setObserver(settings, instance) { + const setObserver = (settings, instance) => { if (shouldUseNative(settings)) { return; } - instance._observer = new IntersectionObserver(function (entries) { + instance._observer = new IntersectionObserver(entries => { intersectionHandler(entries, settings, instance); }, getObserverSettings(settings)); }; - var toArray = function toArray(nodeSet) { - return Array.prototype.slice.call(nodeSet); - }; - var queryElements = function queryElements(settings) { - return settings.container.querySelectorAll(settings.elements_selector); - }; - var excludeManagedElements = function excludeManagedElements(elements) { - return toArray(elements).filter(hasEmptyStatus); - }; - var hasError = function hasError(element) { - return hasStatusError(element); - }; - var filterErrorElements = function filterErrorElements(elements) { - return toArray(elements).filter(hasError); - }; - var getElementsToLoad = function getElementsToLoad(elements, settings) { - return excludeManagedElements(elements || queryElements(settings)); - }; + const toArray = nodeSet => Array.prototype.slice.call(nodeSet); + const queryElements = settings => settings.container.querySelectorAll(settings.elements_selector); + const excludeManagedElements = elements => toArray(elements).filter(hasEmptyStatus); + const hasError = element => hasStatusError(element); + const filterErrorElements = elements => toArray(elements).filter(hasError); + const getElementsToLoad = (elements, settings) => excludeManagedElements(elements || queryElements(settings)); - var retryLazyLoad = function retryLazyLoad(settings, instance) { - var errorElements = filterErrorElements(queryElements(settings)); - errorElements.forEach(function (element) { + const retryLazyLoad = (settings, instance) => { + const errorElements = filterErrorElements(queryElements(settings)); + errorElements.forEach(element => { removeClass(element, settings.class_error); resetStatus(element); }); instance.update(); }; - var setOnlineCheck = function setOnlineCheck(settings, instance) { + const setOnlineCheck = (settings, instance) => { if (!runningOnBrowser) { return; } - instance._onlineHandler = function () { + instance._onlineHandler = () => { retryLazyLoad(settings, instance); }; window.addEventListener("online", instance._onlineHandler); }; - var resetOnlineCheck = function resetOnlineCheck(instance) { + const resetOnlineCheck = instance => { if (!runningOnBrowser) { return; } window.removeEventListener("online", instance._onlineHandler); }; - var LazyLoad = function LazyLoad(customSettings, elements) { - var settings = getExtendedSettings(customSettings); + const LazyLoad = function (customSettings, elements) { + const settings = getExtendedSettings(customSettings); this._settings = settings; this.loadingCount = 0; setObserver(settings, this); @@ -704,9 +652,9 @@ var LazyLoad = (function () { this.update(elements); }; LazyLoad.prototype = { - update: function update(givenNodeset) { - var settings = this._settings; - var elementsToLoad = getElementsToLoad(givenNodeset, settings); + update: function (givenNodeset) { + const settings = this._settings; + const elementsToLoad = getElementsToLoad(givenNodeset, settings); setToLoadCount(this, elementsToLoad.length); if (isBot) { this.loadAll(elementsToLoad); @@ -718,7 +666,7 @@ var LazyLoad = (function () { } updateObserver(this._observer, elementsToLoad); }, - destroy: function destroy() { + destroy: function () { // Observer if (this._observer) { this._observer.disconnect(); @@ -726,7 +674,7 @@ var LazyLoad = (function () { // Clean handlers resetOnlineCheck(this); // Clean custom attributes on elements - queryElements(this._settings).forEach(function (element) { + queryElements(this._settings).forEach(element => { deleteOriginalAttrs(element); }); // Delete all internal props @@ -736,27 +684,26 @@ var LazyLoad = (function () { delete this.loadingCount; delete this.toLoadCount; }, - loadAll: function loadAll(elements) { - var _this = this; - var settings = this._settings; - var elementsToLoad = getElementsToLoad(elements, settings); - elementsToLoad.forEach(function (element) { - unobserve(element, _this); - load(element, settings, _this); + loadAll: function (elements) { + const settings = this._settings; + const elementsToLoad = getElementsToLoad(elements, settings); + elementsToLoad.forEach(element => { + unobserve(element, this); + load(element, settings, this); }); }, - restoreAll: function restoreAll() { - var settings = this._settings; - queryElements(settings).forEach(function (element) { + restoreAll: function () { + const settings = this._settings; + queryElements(settings).forEach(element => { restore(element, settings); }); } }; - LazyLoad.load = function (element, customSettings) { - var settings = getExtendedSettings(customSettings); + LazyLoad.load = (element, customSettings) => { + const settings = getExtendedSettings(customSettings); load(element, settings); }; - LazyLoad.resetStatus = function (element) { + LazyLoad.resetStatus = element => { resetStatus(element); }; diff --git a/dist/lazyload.iife.min.js b/dist/lazyload.iife.min.js index f131508..9e9bbc0 100644 --- a/dist/lazyload.iife.min.js +++ b/dist/lazyload.iife.min.js @@ -1 +1 @@ -var LazyLoad=function(){"use strict";var n="undefined"!=typeof window,t=n&&!("onscroll"in window)||"undefined"!=typeof navigator&&/(gle|ing|ro)bot|crawl|spider/i.test(navigator.userAgent),e=n&&window.devicePixelRatio>1,i={elements_selector:".lazy",container:t||n?document:null,threshold:300,thresholds:null,data_src:"src",data_srcset:"srcset",data_sizes:"sizes",data_bg:"bg",data_bg_hidpi:"bg-hidpi",data_bg_multi:"bg-multi",data_bg_multi_hidpi:"bg-multi-hidpi",data_bg_set:"bg-set",data_poster:"poster",class_applied:"applied",class_loading:"loading",class_loaded:"loaded",class_error:"error",class_entered:"entered",class_exited:"exited",unobserve_completed:!0,unobserve_entered:!1,cancel_on_exit:!0,callback_enter:null,callback_exit:null,callback_applied:null,callback_loading:null,callback_loaded:null,callback_error:null,callback_finish:null,callback_cancel:null,use_native:!1,restore_on_error:!1},o=function(n){return Object.assign({},i,n)},a=function(n,t){var e,i="LazyLoad::Initialized",o=new n(t);try{e=new CustomEvent(i,{detail:{instance:o}})}catch(n){(e=document.createEvent("CustomEvent")).initCustomEvent(i,!1,!1,{instance:o})}window.dispatchEvent(e)},r="src",c="srcset",u="sizes",l="poster",s="llOriginalAttrs",d="data",f="loading",_="loaded",g="applied",v="error",b="native",h="data-",m="ll-status",p=function(n,t){return n.getAttribute(h+t)},E=function(n){return p(n,m)},I=function(n,t){return function(n,t,e){var i=h+t;null!==e?n.setAttribute(i,e):n.removeAttribute(i)}(n,m,t)},k=function(n){return I(n,null)},A=function(n){return null===E(n)},L=function(n){return E(n)===b},y=[f,_,g,v],w=function(n,t,e,i){n&&"function"==typeof n&&(void 0===i?void 0===e?n(t):n(t,e):n(t,e,i))},C=function(t,e){n&&""!==e&&t.classList.add(e)},O=function(t,e){n&&""!==e&&t.classList.remove(e)},x=function(n){return n.llTempImage},M=function(n,t){if(t){var e=t._observer;e&&e.unobserve(n)}},z=function(n,t){n&&(n.loadingCount+=t)},N=function(n,t){n&&(n.toLoadCount=t)},R=function(n){for(var t,e=[],i=0;t=n.children[i];i+=1)"SOURCE"===t.tagName&&e.push(t);return e},T=function(n,t){var e=n.parentNode;e&&"PICTURE"===e.tagName&&R(e).forEach(t)},G=function(n,t){R(n).forEach(t)},D=[r],H=[r,l],V=[r,c,u],F=[d],B=function(n){return!!n[s]},J=function(n){return n[s]},S=function(n){return delete n[s]},j=function(n,t){if(!B(n)){var e={};t.forEach((function(t){e[t]=n.getAttribute(t)})),n[s]=e}},P=function(n,t){if(B(n)){var e=J(n);t.forEach((function(t){!function(n,t,e){e?n.setAttribute(t,e):n.removeAttribute(t)}(n,t,e[t])}))}},U=function(n,t,e){C(n,t.class_applied),I(n,g),e&&(t.unobserve_completed&&M(n,t),w(t.callback_applied,n,e))},q=function(n,t,e){C(n,t.class_loading),I(n,f),e&&(z(e,1),w(t.callback_loading,n,e))},K=function(n,t,e){e&&n.setAttribute(t,e)},Q=function(n,t){K(n,u,p(n,t.data_sizes)),K(n,c,p(n,t.data_srcset)),K(n,r,p(n,t.data_src))},W={IMG:function(n,t){T(n,(function(n){j(n,V),Q(n,t)})),j(n,V),Q(n,t)},IFRAME:function(n,t){j(n,D),K(n,r,p(n,t.data_src))},VIDEO:function(n,t){G(n,(function(n){j(n,D),K(n,r,p(n,t.data_src))})),j(n,H),K(n,l,p(n,t.data_poster)),K(n,r,p(n,t.data_src)),n.load()},OBJECT:function(n,t){j(n,F),K(n,d,p(n,t.data_src))}},X=["IMG","IFRAME","VIDEO","OBJECT"],Y=function(n,t){!t||function(n){return n.loadingCount>0}(t)||function(n){return n.toLoadCount>0}(t)||w(n.callback_finish,t)},Z=function(n,t,e){n.addEventListener(t,e),n.llEvLisnrs[t]=e},$=function(n,t,e){n.removeEventListener(t,e)},nn=function(n){return!!n.llEvLisnrs},tn=function(n){if(nn(n)){var t=n.llEvLisnrs;for(var e in t){var i=t[e];$(n,e,i)}delete n.llEvLisnrs}},en=function(n,t,e){!function(n){delete n.llTempImage}(n),z(e,-1),function(n){n&&(n.toLoadCount-=1)}(e),O(n,t.class_loading),t.unobserve_completed&&M(n,e)},on=function(n,t,e){var i=x(n)||n;nn(i)||function(n,t,e){nn(n)||(n.llEvLisnrs={});var i="VIDEO"===n.tagName?"loadeddata":"load";Z(n,i,t),Z(n,"error",e)}(i,(function(o){!function(n,t,e,i){var o=L(t);en(t,e,i),C(t,e.class_loaded),I(t,_),w(e.callback_loaded,t,i),o||Y(e,i)}(0,n,t,e),tn(i)}),(function(o){!function(n,t,e,i){var o=L(t);en(t,e,i),C(t,e.class_error),I(t,v),w(e.callback_error,t,i),e.restore_on_error&&P(t,V),o||Y(e,i)}(0,n,t,e),tn(i)}))},an=function(n,t,i){!function(n){return X.indexOf(n.tagName)>-1}(n)?function(n,t,i){!function(n){n.llTempImage=document.createElement("IMG")}(n),on(n,t,i),function(n){B(n)||(n[s]={backgroundImage:n.style.backgroundImage})}(n),function(n,t,i){var o=p(n,t.data_bg),a=p(n,t.data_bg_hidpi),c=e&&a?a:o;c&&(n.style.backgroundImage='url("'.concat(c,'")'),x(n).setAttribute(r,c),q(n,t,i))}(n,t,i),function(n,t,i){var o=p(n,t.data_bg_multi),a=p(n,t.data_bg_multi_hidpi),r=e&&a?a:o;r&&(n.style.backgroundImage=r,U(n,t,i))}(n,t,i),function(n,t,e){var i=p(n,t.data_bg_set);if(i){var o=i.split("|").map((function(n){return"image-set(".concat(n,")")}));n.style.backgroundImage=o.join(),U(n,t,e)}}(n,t,i)}(n,t,i):function(n,t,e){on(n,t,e),function(n,t,e){var i=W[n.tagName];i&&(i(n,t),q(n,t,e))}(n,t,e)}(n,t,i)},rn=function(n){n.removeAttribute(r),n.removeAttribute(c),n.removeAttribute(u)},cn=function(n){T(n,(function(n){P(n,V)})),P(n,V)},un={IMG:cn,IFRAME:function(n){P(n,D)},VIDEO:function(n){G(n,(function(n){P(n,D)})),P(n,H),n.load()},OBJECT:function(n){P(n,F)}},ln=function(n,t){(function(n){var t=un[n.tagName];t?t(n):function(n){if(B(n)){var t=J(n);n.style.backgroundImage=t.backgroundImage}}(n)})(n),function(n,t){A(n)||L(n)||(O(n,t.class_entered),O(n,t.class_exited),O(n,t.class_applied),O(n,t.class_loading),O(n,t.class_loaded),O(n,t.class_error))}(n,t),k(n),S(n)},sn=["IMG","IFRAME","VIDEO"],dn=function(n){return n.use_native&&"loading"in HTMLImageElement.prototype},fn=function(n,t,e){n.forEach((function(n){return function(n){return n.isIntersecting||n.intersectionRatio>0}(n)?function(n,t,e,i){var o=function(n){return y.indexOf(E(n))>=0}(n);I(n,"entered"),C(n,e.class_entered),O(n,e.class_exited),function(n,t,e){t.unobserve_entered&&M(n,e)}(n,e,i),w(e.callback_enter,n,t,i),o||an(n,e,i)}(n.target,n,t,e):function(n,t,e,i){A(n)||(C(n,e.class_exited),function(n,t,e,i){e.cancel_on_exit&&function(n){return E(n)===f}(n)&&"IMG"===n.tagName&&(tn(n),function(n){T(n,(function(n){rn(n)})),rn(n)}(n),cn(n),O(n,e.class_loading),z(i,-1),k(n),w(e.callback_cancel,n,t,i))}(n,t,e,i),w(e.callback_exit,n,t,i))}(n.target,n,t,e)}))},_n=function(n){return Array.prototype.slice.call(n)},gn=function(n){return n.container.querySelectorAll(n.elements_selector)},vn=function(n){return function(n){return E(n)===v}(n)},bn=function(n,t){return function(n){return _n(n).filter(A)}(n||gn(t))},hn=function(t,e){var i=o(t);this._settings=i,this.loadingCount=0,function(n,t){dn(n)||(t._observer=new IntersectionObserver((function(e){fn(e,n,t)}),function(n){return{root:n.container===document?null:n.container,rootMargin:n.thresholds||n.threshold+"px"}}(n)))}(i,this),function(t,e){n&&(e._onlineHandler=function(){!function(n,t){var e;(e=gn(n),_n(e).filter(vn)).forEach((function(t){O(t,n.class_error),k(t)})),t.update()}(t,e)},window.addEventListener("online",e._onlineHandler))}(i,this),this.update(e)};return hn.prototype={update:function(n){var e,i,o=this._settings,a=bn(n,o);N(this,a.length),t?this.loadAll(a):dn(o)?function(n,t,e){n.forEach((function(n){-1!==sn.indexOf(n.tagName)&&function(n,t,e){n.setAttribute("loading","lazy"),on(n,t,e),function(n,t){var e=W[n.tagName];e&&e(n,t)}(n,t),I(n,b)}(n,t,e)})),N(e,0)}(a,o,this):(i=a,function(n){n.disconnect()}(e=this._observer),function(n,t){t.forEach((function(t){n.observe(t)}))}(e,i))},destroy:function(){this._observer&&this._observer.disconnect(),n&&window.removeEventListener("online",this._onlineHandler),gn(this._settings).forEach((function(n){S(n)})),delete this._observer,delete this._settings,delete this._onlineHandler,delete this.loadingCount,delete this.toLoadCount},loadAll:function(n){var t=this,e=this._settings;bn(n,e).forEach((function(n){M(n,t),an(n,e,t)}))},restoreAll:function(){var n=this._settings;gn(n).forEach((function(t){ln(t,n)}))}},hn.load=function(n,t){var e=o(t);an(n,e)},hn.resetStatus=function(n){k(n)},n&&function(n,t){if(t)if(t.length)for(var e,i=0;e=t[i];i+=1)a(n,e);else a(n,t)}(hn,window.lazyLoadOptions),hn}(); +var LazyLoad=function(){"use strict";const e="undefined"!=typeof window,t=e&&!("onscroll"in window)||"undefined"!=typeof navigator&&/(gle|ing|ro)bot|crawl|spider/i.test(navigator.userAgent),a=e&&window.devicePixelRatio>1,s={elements_selector:".lazy",container:t||e?document:null,threshold:300,thresholds:null,data_src:"src",data_srcset:"srcset",data_sizes:"sizes",data_bg:"bg",data_bg_hidpi:"bg-hidpi",data_bg_multi:"bg-multi",data_bg_multi_hidpi:"bg-multi-hidpi",data_bg_set:"bg-set",data_poster:"poster",class_applied:"applied",class_loading:"loading",class_loaded:"loaded",class_error:"error",class_entered:"entered",class_exited:"exited",unobserve_completed:!0,unobserve_entered:!1,cancel_on_exit:!0,callback_enter:null,callback_exit:null,callback_applied:null,callback_loading:null,callback_loaded:null,callback_error:null,callback_finish:null,callback_cancel:null,use_native:!1,restore_on_error:!1},n=e=>Object.assign({},s,e),l=function(e,t){let a;const s="LazyLoad::Initialized",n=new e(t);try{a=new CustomEvent(s,{detail:{instance:n}})}catch(e){a=document.createEvent("CustomEvent"),a.initCustomEvent(s,!1,!1,{instance:n})}window.dispatchEvent(a)},o="src",r="srcset",i="sizes",c="poster",d="llOriginalAttrs",_="data",u="loading",g="loaded",b="applied",h="error",m="native",p="data-",v="ll-status",f=(e,t)=>e.getAttribute(p+t),E=e=>f(e,v),I=(e,t)=>((e,t,a)=>{const s=p+t;null!==a?e.setAttribute(s,a):e.removeAttribute(s)})(e,v,t),k=e=>I(e,null),A=e=>null===E(e),L=e=>E(e)===m,y=[u,g,b,h],w=(e,t,a,s)=>{e&&"function"==typeof e&&(void 0===s?void 0===a?e(t):e(t,a):e(t,a,s))},C=(t,a)=>{e&&""!==a&&t.classList.add(a)},O=(t,a)=>{e&&""!==a&&t.classList.remove(a)},x=e=>e.llTempImage,M=(e,t)=>{if(!t)return;const a=t._observer;a&&a.unobserve(e)},z=(e,t)=>{e&&(e.loadingCount+=t)},N=(e,t)=>{e&&(e.toLoadCount=t)},R=e=>{let t=[];for(let a,s=0;a=e.children[s];s+=1)"SOURCE"===a.tagName&&t.push(a);return t},T=(e,t)=>{const a=e.parentNode;a&&"PICTURE"===a.tagName&&R(a).forEach(t)},G=(e,t)=>{R(e).forEach(t)},D=[o],H=[o,c],V=[o,r,i],F=[_],B=e=>!!e[d],J=e=>e[d],S=e=>delete e[d],j=(e,t)=>{if(B(e))return;const a={};t.forEach((t=>{a[t]=e.getAttribute(t)})),e[d]=a},P=(e,t)=>{if(!B(e))return;const a=J(e);t.forEach((t=>{((e,t,a)=>{a?e.setAttribute(t,a):e.removeAttribute(t)})(e,t,a[t])}))},U=(e,t,a)=>{C(e,t.class_applied),I(e,b),a&&(t.unobserve_completed&&M(e,t),w(t.callback_applied,e,a))},$=(e,t,a)=>{C(e,t.class_loading),I(e,u),a&&(z(a,1),w(t.callback_loading,e,a))},q=(e,t,a)=>{a&&e.setAttribute(t,a)},K=(e,t)=>{q(e,i,f(e,t.data_sizes)),q(e,r,f(e,t.data_srcset)),q(e,o,f(e,t.data_src))},Q={IMG:(e,t)=>{T(e,(e=>{j(e,V),K(e,t)})),j(e,V),K(e,t)},IFRAME:(e,t)=>{j(e,D),q(e,o,f(e,t.data_src))},VIDEO:(e,t)=>{G(e,(e=>{j(e,D),q(e,o,f(e,t.data_src))})),j(e,H),q(e,c,f(e,t.data_poster)),q(e,o,f(e,t.data_src)),e.load()},OBJECT:(e,t)=>{j(e,F),q(e,_,f(e,t.data_src))}},W=["IMG","IFRAME","VIDEO","OBJECT"],X=(e,t)=>{!t||(e=>e.loadingCount>0)(t)||(e=>e.toLoadCount>0)(t)||w(e.callback_finish,t)},Y=(e,t,a)=>{e.addEventListener(t,a),e.llEvLisnrs[t]=a},Z=(e,t,a)=>{e.removeEventListener(t,a)},ee=e=>!!e.llEvLisnrs,te=e=>{if(!ee(e))return;const t=e.llEvLisnrs;for(let a in t){const s=t[a];Z(e,a,s)}delete e.llEvLisnrs},ae=(e,t,a)=>{(e=>{delete e.llTempImage})(e),z(a,-1),(e=>{e&&(e.toLoadCount-=1)})(a),O(e,t.class_loading),t.unobserve_completed&&M(e,a)},se=(e,t,a)=>{const s=x(e)||e;ee(s)||((e,t,a)=>{ee(e)||(e.llEvLisnrs={});const s="VIDEO"===e.tagName?"loadeddata":"load";Y(e,s,t),Y(e,"error",a)})(s,(n=>{((e,t,a,s)=>{const n=L(t);ae(t,a,s),C(t,a.class_loaded),I(t,g),w(a.callback_loaded,t,s),n||X(a,s)})(0,e,t,a),te(s)}),(n=>{((e,t,a,s)=>{const n=L(t);ae(t,a,s),C(t,a.class_error),I(t,h),w(a.callback_error,t,s),a.restore_on_error&&P(t,V),n||X(a,s)})(0,e,t,a),te(s)}))},ne=(e,t,s)=>{(e=>W.indexOf(e.tagName)>-1)(e)?((e,t,a)=>{se(e,t,a),((e,t,a)=>{const s=Q[e.tagName];s&&(s(e,t),$(e,t,a))})(e,t,a)})(e,t,s):((e,t,s)=>{(e=>{e.llTempImage=document.createElement("IMG")})(e),se(e,t,s),(e=>{B(e)||(e[d]={backgroundImage:e.style.backgroundImage})})(e),((e,t,s)=>{const n=f(e,t.data_bg),l=f(e,t.data_bg_hidpi),r=a&&l?l:n;r&&(e.style.backgroundImage=`url("${r}")`,x(e).setAttribute(o,r),$(e,t,s))})(e,t,s),((e,t,s)=>{const n=f(e,t.data_bg_multi),l=f(e,t.data_bg_multi_hidpi),o=a&&l?l:n;o&&(e.style.backgroundImage=o,U(e,t,s))})(e,t,s),((e,t,a)=>{const s=f(e,t.data_bg_set);if(!s)return;let n=s.split("|").map((e=>`image-set(${e})`));e.style.backgroundImage=n.join(),U(e,t,a)})(e,t,s)})(e,t,s)},le=e=>{e.removeAttribute(o),e.removeAttribute(r),e.removeAttribute(i)},oe=e=>{T(e,(e=>{P(e,V)})),P(e,V)},re={IMG:oe,IFRAME:e=>{P(e,D)},VIDEO:e=>{G(e,(e=>{P(e,D)})),P(e,H),e.load()},OBJECT:e=>{P(e,F)}},ie=(e,t)=>{(e=>{const t=re[e.tagName];t?t(e):(e=>{if(!B(e))return;const t=J(e);e.style.backgroundImage=t.backgroundImage})(e)})(e),((e,t)=>{A(e)||L(e)||(O(e,t.class_entered),O(e,t.class_exited),O(e,t.class_applied),O(e,t.class_loading),O(e,t.class_loaded),O(e,t.class_error))})(e,t),k(e),S(e)},ce=["IMG","IFRAME","VIDEO"],de=e=>e.use_native&&"loading"in HTMLImageElement.prototype,_e=(e,t,a)=>{e.forEach((e=>(e=>e.isIntersecting||e.intersectionRatio>0)(e)?((e,t,a,s)=>{const n=(e=>y.indexOf(E(e))>=0)(e);I(e,"entered"),C(e,a.class_entered),O(e,a.class_exited),((e,t,a)=>{t.unobserve_entered&&M(e,a)})(e,a,s),w(a.callback_enter,e,t,s),n||ne(e,a,s)})(e.target,e,t,a):((e,t,a,s)=>{A(e)||(C(e,a.class_exited),((e,t,a,s)=>{a.cancel_on_exit&&(e=>E(e)===u)(e)&&"IMG"===e.tagName&&(te(e),(e=>{T(e,(e=>{le(e)})),le(e)})(e),oe(e),O(e,a.class_loading),z(s,-1),k(e),w(a.callback_cancel,e,t,s))})(e,t,a,s),w(a.callback_exit,e,t,s))})(e.target,e,t,a)))},ue=e=>Array.prototype.slice.call(e),ge=e=>e.container.querySelectorAll(e.elements_selector),be=e=>(e=>E(e)===h)(e),he=(e,t)=>(e=>ue(e).filter(A))(e||ge(t)),me=function(t,a){const s=n(t);this._settings=s,this.loadingCount=0,((e,t)=>{de(e)||(t._observer=new IntersectionObserver((a=>{_e(a,e,t)}),(e=>({root:e.container===document?null:e.container,rootMargin:e.thresholds||e.threshold+"px"}))(e)))})(s,this),((t,a)=>{e&&(a._onlineHandler=()=>{((e,t)=>{var a;(a=ge(e),ue(a).filter(be)).forEach((t=>{O(t,e.class_error),k(t)})),t.update()})(t,a)},window.addEventListener("online",a._onlineHandler))})(s,this),this.update(a)};return me.prototype={update:function(e){const a=this._settings,s=he(e,a);var n,l;N(this,s.length),t?this.loadAll(s):de(a)?((e,t,a)=>{e.forEach((e=>{-1!==ce.indexOf(e.tagName)&&((e,t,a)=>{e.setAttribute("loading","lazy"),se(e,t,a),((e,t)=>{const a=Q[e.tagName];a&&a(e,t)})(e,t),I(e,m)})(e,t,a)})),N(a,0)})(s,a,this):(l=s,(e=>{e.disconnect()})(n=this._observer),((e,t)=>{t.forEach((t=>{e.observe(t)}))})(n,l))},destroy:function(){this._observer&&this._observer.disconnect(),e&&window.removeEventListener("online",this._onlineHandler),ge(this._settings).forEach((e=>{S(e)})),delete this._observer,delete this._settings,delete this._onlineHandler,delete this.loadingCount,delete this.toLoadCount},loadAll:function(e){const t=this._settings;he(e,t).forEach((e=>{M(e,this),ne(e,t,this)}))},restoreAll:function(){const e=this._settings;ge(e).forEach((t=>{ie(t,e)}))}},me.load=(e,t)=>{const a=n(t);ne(e,a)},me.resetStatus=e=>{k(e)},e&&((e,t)=>{if(t)if(t.length)for(let a,s=0;a=t[s];s+=1)l(e,a);else l(e,t)})(me,window.lazyLoadOptions),me}(); diff --git a/dist/lazyload.js b/dist/lazyload.js index 811f1fe..104baa2 100644 --- a/dist/lazyload.js +++ b/dist/lazyload.js @@ -4,11 +4,11 @@ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.LazyLoad = factory()); })(this, (function () { 'use strict'; - var runningOnBrowser = typeof window !== "undefined"; - var isBot = runningOnBrowser && !("onscroll" in window) || typeof navigator !== "undefined" && /(gle|ing|ro)bot|crawl|spider/i.test(navigator.userAgent); - var isHiDpi = runningOnBrowser && window.devicePixelRatio > 1; + const runningOnBrowser = typeof window !== "undefined"; + const isBot = runningOnBrowser && !("onscroll" in window) || typeof navigator !== "undefined" && /(gle|ing|ro)bot|crawl|spider/i.test(navigator.userAgent); + const isHiDpi = runningOnBrowser && window.devicePixelRatio > 1; - var defaultSettings = { + const defaultSettings = { elements_selector: ".lazy", container: isBot || runningOnBrowser ? document : null, threshold: 300, @@ -42,27 +42,27 @@ use_native: false, restore_on_error: false }; - var getExtendedSettings = function getExtendedSettings(customSettings) { + const getExtendedSettings = customSettings => { return Object.assign({}, defaultSettings, customSettings); }; /* Creates instance and notifies it through the window element */ - var createInstance = function createInstance(classObj, options) { - var event; - var eventString = "LazyLoad::Initialized"; - var instance = new classObj(options); + const createInstance = function (classObj, options) { + let event; + const eventString = "LazyLoad::Initialized"; + const instance = new classObj(options); try { // Works in modern browsers event = new CustomEvent(eventString, { detail: { - instance: instance + instance } }); } catch (err) { // Works in Internet Explorer (all versions) event = document.createEvent("CustomEvent"); event.initCustomEvent(eventString, false, false, { - instance: instance + instance }); } window.dispatchEvent(event); @@ -70,7 +70,7 @@ /* Auto initialization of one or more instances of LazyLoad, depending on the options passed in (plain object or an array) */ - var autoInitialize = function autoInitialize(classObj, options) { + const autoInitialize = (classObj, options) => { if (!options) { return; } @@ -79,66 +79,50 @@ createInstance(classObj, options); } else { // Array of objects - for (var i = 0, optionsItem; optionsItem = options[i]; i += 1) { + for (let i = 0, optionsItem; optionsItem = options[i]; i += 1) { createInstance(classObj, optionsItem); } } }; - var SRC = "src"; - var SRCSET = "srcset"; - var SIZES = "sizes"; - var POSTER = "poster"; - var ORIGINALS = "llOriginalAttrs"; - var DATA = "data"; + const SRC = "src"; + const SRCSET = "srcset"; + const SIZES = "sizes"; + const POSTER = "poster"; + const ORIGINALS = "llOriginalAttrs"; + const DATA = "data"; - var statusLoading = "loading"; - var statusLoaded = "loaded"; - var statusApplied = "applied"; - var statusEntered = "entered"; - var statusError = "error"; - var statusNative = "native"; + const statusLoading = "loading"; + const statusLoaded = "loaded"; + const statusApplied = "applied"; + const statusEntered = "entered"; + const statusError = "error"; + const statusNative = "native"; - var dataPrefix = "data-"; - var statusDataName = "ll-status"; - var getData = function getData(element, attribute) { + const dataPrefix = "data-"; + const statusDataName = "ll-status"; + const getData = (element, attribute) => { return element.getAttribute(dataPrefix + attribute); }; - var setData = function setData(element, attribute, value) { - var attrName = dataPrefix + attribute; + const setData = (element, attribute, value) => { + const attrName = dataPrefix + attribute; if (value === null) { element.removeAttribute(attrName); return; } element.setAttribute(attrName, value); }; - var getStatus = function getStatus(element) { - return getData(element, statusDataName); - }; - var setStatus = function setStatus(element, status) { - return setData(element, statusDataName, status); - }; - var resetStatus = function resetStatus(element) { - return setStatus(element, null); - }; - var hasEmptyStatus = function hasEmptyStatus(element) { - return getStatus(element) === null; - }; - var hasStatusLoading = function hasStatusLoading(element) { - return getStatus(element) === statusLoading; - }; - var hasStatusError = function hasStatusError(element) { - return getStatus(element) === statusError; - }; - var hasStatusNative = function hasStatusNative(element) { - return getStatus(element) === statusNative; - }; - var statusesAfterLoading = [statusLoading, statusLoaded, statusApplied, statusError]; - var hadStartedLoading = function hadStartedLoading(element) { - return statusesAfterLoading.indexOf(getStatus(element)) >= 0; - }; - - var safeCallback = function safeCallback(callback, arg1, arg2, arg3) { + const getStatus = element => getData(element, statusDataName); + const setStatus = (element, status) => setData(element, statusDataName, status); + const resetStatus = element => setStatus(element, null); + const hasEmptyStatus = element => getStatus(element) === null; + const hasStatusLoading = element => getStatus(element) === statusLoading; + const hasStatusError = element => getStatus(element) === statusError; + const hasStatusNative = element => getStatus(element) === statusNative; + const statusesAfterLoading = [statusLoading, statusLoaded, statusApplied, statusError]; + const hadStartedLoading = element => statusesAfterLoading.indexOf(getStatus(element)) >= 0; + + const safeCallback = (callback, arg1, arg2, arg3) => { if (!callback || typeof callback !== 'function') { return; } @@ -153,7 +137,7 @@ callback(arg1); }; - var addClass = function addClass(element, className) { + const addClass = (element, className) => { if (!runningOnBrowser) { return; } @@ -162,7 +146,7 @@ } element.classList.add(className); }; - var removeClass = function removeClass(element, className) { + const removeClass = (element, className) => { if (!runningOnBrowser) { return; } @@ -172,97 +156,85 @@ element.classList.remove(className); }; - var addTempImage = function addTempImage(element) { + const addTempImage = element => { element.llTempImage = document.createElement("IMG"); }; - var deleteTempImage = function deleteTempImage(element) { + const deleteTempImage = element => { delete element.llTempImage; }; - var getTempImage = function getTempImage(element) { - return element.llTempImage; - }; + const getTempImage = element => element.llTempImage; - var unobserve = function unobserve(element, instance) { + const unobserve = (element, instance) => { if (!instance) return; - var observer = instance._observer; + const observer = instance._observer; if (!observer) return; observer.unobserve(element); }; - var resetObserver = function resetObserver(observer) { + const resetObserver = observer => { observer.disconnect(); }; - var unobserveEntered = function unobserveEntered(element, settings, instance) { + const unobserveEntered = (element, settings, instance) => { if (settings.unobserve_entered) unobserve(element, instance); }; - var updateLoadingCount = function updateLoadingCount(instance, delta) { + const updateLoadingCount = (instance, delta) => { if (!instance) return; instance.loadingCount += delta; }; - var decreaseToLoadCount = function decreaseToLoadCount(instance) { + const decreaseToLoadCount = instance => { if (!instance) return; instance.toLoadCount -= 1; }; - var setToLoadCount = function setToLoadCount(instance, value) { + const setToLoadCount = (instance, value) => { if (!instance) return; instance.toLoadCount = value; }; - var isSomethingLoading = function isSomethingLoading(instance) { - return instance.loadingCount > 0; - }; - var haveElementsToLoad = function haveElementsToLoad(instance) { - return instance.toLoadCount > 0; - }; + const isSomethingLoading = instance => instance.loadingCount > 0; + const haveElementsToLoad = instance => instance.toLoadCount > 0; - var getSourceTags = function getSourceTags(parentTag) { - var sourceTags = []; - for (var i = 0, childTag; childTag = parentTag.children[i]; i += 1) { + const getSourceTags = parentTag => { + let sourceTags = []; + for (let i = 0, childTag; childTag = parentTag.children[i]; i += 1) { if (childTag.tagName === "SOURCE") { sourceTags.push(childTag); } } return sourceTags; }; - var forEachPictureSource = function forEachPictureSource(element, fn) { - var parent = element.parentNode; + const forEachPictureSource = (element, fn) => { + const parent = element.parentNode; if (!parent || parent.tagName !== "PICTURE") { return; } - var sourceTags = getSourceTags(parent); + let sourceTags = getSourceTags(parent); sourceTags.forEach(fn); }; - var forEachVideoSource = function forEachVideoSource(element, fn) { - var sourceTags = getSourceTags(element); + const forEachVideoSource = (element, fn) => { + let sourceTags = getSourceTags(element); sourceTags.forEach(fn); }; - var attrsSrc = [SRC]; - var attrsSrcPoster = [SRC, POSTER]; - var attrsSrcSrcsetSizes = [SRC, SRCSET, SIZES]; - var attrsData = [DATA]; - var hasOriginalAttrs = function hasOriginalAttrs(element) { - return !!element[ORIGINALS]; - }; - var getOriginalAttrs = function getOriginalAttrs(element) { - return element[ORIGINALS]; - }; - var deleteOriginalAttrs = function deleteOriginalAttrs(element) { - return delete element[ORIGINALS]; - }; + const attrsSrc = [SRC]; + const attrsSrcPoster = [SRC, POSTER]; + const attrsSrcSrcsetSizes = [SRC, SRCSET, SIZES]; + const attrsData = [DATA]; + const hasOriginalAttrs = element => !!element[ORIGINALS]; + const getOriginalAttrs = element => element[ORIGINALS]; + const deleteOriginalAttrs = element => delete element[ORIGINALS]; // ## SAVE ## - var setOriginalsObject = function setOriginalsObject(element, attributes) { + const setOriginalsObject = (element, attributes) => { if (hasOriginalAttrs(element)) { return; } - var originals = {}; - attributes.forEach(function (attribute) { + const originals = {}; + attributes.forEach(attribute => { originals[attribute] = element.getAttribute(attribute); }); element[ORIGINALS] = originals; }; - var saveOriginalBackgroundStyle = function saveOriginalBackgroundStyle(element) { + const saveOriginalBackgroundStyle = element => { if (hasOriginalAttrs(element)) { return; } @@ -273,31 +245,31 @@ // ## RESTORE ## - var setOrResetAttribute = function setOrResetAttribute(element, attrName, value) { + const setOrResetAttribute = (element, attrName, value) => { if (!value) { element.removeAttribute(attrName); return; } element.setAttribute(attrName, value); }; - var restoreOriginalAttrs = function restoreOriginalAttrs(element, attributes) { + const restoreOriginalAttrs = (element, attributes) => { if (!hasOriginalAttrs(element)) { return; } - var originals = getOriginalAttrs(element); - attributes.forEach(function (attribute) { + const originals = getOriginalAttrs(element); + attributes.forEach(attribute => { setOrResetAttribute(element, attribute, originals[attribute]); }); }; - var restoreOriginalBgImage = function restoreOriginalBgImage(element) { + const restoreOriginalBgImage = element => { if (!hasOriginalAttrs(element)) { return; } - var originals = getOriginalAttrs(element); + const originals = getOriginalAttrs(element); element.style.backgroundImage = originals.backgroundImage; }; - var manageApplied = function manageApplied(element, settings, instance) { + const manageApplied = (element, settings, instance) => { addClass(element, settings.class_applied); setStatus(element, statusApplied); // Instance is not provided when loading is called from static class @@ -308,7 +280,7 @@ } safeCallback(settings.callback_applied, element, instance); }; - var manageLoading = function manageLoading(element, settings, instance) { + const manageLoading = (element, settings, instance) => { addClass(element, settings.class_loading); setStatus(element, statusLoading); // Instance is not provided when loading is called from static class @@ -316,31 +288,31 @@ updateLoadingCount(instance, +1); safeCallback(settings.callback_loading, element, instance); }; - var setAttributeIfValue = function setAttributeIfValue(element, attrName, value) { + const setAttributeIfValue = (element, attrName, value) => { if (!value) { return; } element.setAttribute(attrName, value); }; - var setImageAttributes = function setImageAttributes(element, settings) { + const setImageAttributes = (element, settings) => { setAttributeIfValue(element, SIZES, getData(element, settings.data_sizes)); setAttributeIfValue(element, SRCSET, getData(element, settings.data_srcset)); setAttributeIfValue(element, SRC, getData(element, settings.data_src)); }; - var setSourcesImg = function setSourcesImg(imgEl, settings) { - forEachPictureSource(imgEl, function (sourceTag) { + const setSourcesImg = (imgEl, settings) => { + forEachPictureSource(imgEl, sourceTag => { setOriginalsObject(sourceTag, attrsSrcSrcsetSizes); setImageAttributes(sourceTag, settings); }); setOriginalsObject(imgEl, attrsSrcSrcsetSizes); setImageAttributes(imgEl, settings); }; - var setSourcesIframe = function setSourcesIframe(iframe, settings) { + const setSourcesIframe = (iframe, settings) => { setOriginalsObject(iframe, attrsSrc); setAttributeIfValue(iframe, SRC, getData(iframe, settings.data_src)); }; - var setSourcesVideo = function setSourcesVideo(videoEl, settings) { - forEachVideoSource(videoEl, function (sourceEl) { + const setSourcesVideo = (videoEl, settings) => { + forEachVideoSource(videoEl, sourceEl => { setOriginalsObject(sourceEl, attrsSrc); setAttributeIfValue(sourceEl, SRC, getData(sourceEl, settings.data_src)); }); @@ -349,16 +321,16 @@ setAttributeIfValue(videoEl, SRC, getData(videoEl, settings.data_src)); videoEl.load(); }; - var setSourcesObject = function setSourcesObject(object, settings) { + const setSourcesObject = (object, settings) => { setOriginalsObject(object, attrsData); setAttributeIfValue(object, DATA, getData(object, settings.data_src)); }; - var setBackground = function setBackground(element, settings, instance) { - var bg1xValue = getData(element, settings.data_bg); - var bgHiDpiValue = getData(element, settings.data_bg_hidpi); - var bgDataValue = isHiDpi && bgHiDpiValue ? bgHiDpiValue : bg1xValue; + const setBackground = (element, settings, instance) => { + const bg1xValue = getData(element, settings.data_bg); + const bgHiDpiValue = getData(element, settings.data_bg_hidpi); + const bgDataValue = isHiDpi && bgHiDpiValue ? bgHiDpiValue : bg1xValue; if (!bgDataValue) return; - element.style.backgroundImage = "url(\"".concat(bgDataValue, "\")"); + element.style.backgroundImage = `url("${bgDataValue}")`; getTempImage(element).setAttribute(SRC, bgDataValue); manageLoading(element, settings, instance); }; @@ -366,43 +338,41 @@ // NOTE: THE TEMP IMAGE TRICK CANNOT BE DONE WITH data-multi-bg // BECAUSE INSIDE ITS VALUES MUST BE WRAPPED WITH URL() AND ONE OF THEM // COULD BE A GRADIENT BACKGROUND IMAGE - var setMultiBackground = function setMultiBackground(element, settings, instance) { - var bg1xValue = getData(element, settings.data_bg_multi); - var bgHiDpiValue = getData(element, settings.data_bg_multi_hidpi); - var bgDataValue = isHiDpi && bgHiDpiValue ? bgHiDpiValue : bg1xValue; + const setMultiBackground = (element, settings, instance) => { + const bg1xValue = getData(element, settings.data_bg_multi); + const bgHiDpiValue = getData(element, settings.data_bg_multi_hidpi); + const bgDataValue = isHiDpi && bgHiDpiValue ? bgHiDpiValue : bg1xValue; if (!bgDataValue) { return; } element.style.backgroundImage = bgDataValue; manageApplied(element, settings, instance); }; - var setImgsetBackground = function setImgsetBackground(element, settings, instance) { - var bgImgSetDataValue = getData(element, settings.data_bg_set); + const setImgsetBackground = (element, settings, instance) => { + const bgImgSetDataValue = getData(element, settings.data_bg_set); if (!bgImgSetDataValue) { return; } - var imgSetValues = bgImgSetDataValue.split("|"); - var bgImageValues = imgSetValues.map(function (value) { - return "image-set(".concat(value, ")"); - }); + const imgSetValues = bgImgSetDataValue.split("|"); + let bgImageValues = imgSetValues.map(value => `image-set(${value})`); element.style.backgroundImage = bgImageValues.join(); manageApplied(element, settings, instance); }; - var setSourcesFunctions = { + const setSourcesFunctions = { IMG: setSourcesImg, IFRAME: setSourcesIframe, VIDEO: setSourcesVideo, OBJECT: setSourcesObject }; - var setSourcesNative = function setSourcesNative(element, settings) { - var setSourcesFunction = setSourcesFunctions[element.tagName]; + const setSourcesNative = (element, settings) => { + const setSourcesFunction = setSourcesFunctions[element.tagName]; if (!setSourcesFunction) { return; } setSourcesFunction(element, settings); }; - var setSources = function setSources(element, settings, instance) { - var setSourcesFunction = setSourcesFunctions[element.tagName]; + const setSources = (element, settings, instance) => { + const setSourcesFunction = setSourcesFunctions[element.tagName]; if (!setSourcesFunction) { return; } @@ -410,43 +380,41 @@ manageLoading(element, settings, instance); }; - var elementsWithLoadEvent = ["IMG", "IFRAME", "VIDEO", "OBJECT"]; - var hasLoadEvent = function hasLoadEvent(element) { - return elementsWithLoadEvent.indexOf(element.tagName) > -1; - }; - var checkFinish = function checkFinish(settings, instance) { + const elementsWithLoadEvent = ["IMG", "IFRAME", "VIDEO", "OBJECT"]; + const hasLoadEvent = element => elementsWithLoadEvent.indexOf(element.tagName) > -1; + const checkFinish = (settings, instance) => { if (instance && !isSomethingLoading(instance) && !haveElementsToLoad(instance)) { safeCallback(settings.callback_finish, instance); } }; - var addEventListener = function addEventListener(element, eventName, handler) { + const addEventListener = (element, eventName, handler) => { element.addEventListener(eventName, handler); element.llEvLisnrs[eventName] = handler; }; - var removeEventListener = function removeEventListener(element, eventName, handler) { + const removeEventListener = (element, eventName, handler) => { element.removeEventListener(eventName, handler); }; - var hasEventListeners = function hasEventListeners(element) { + const hasEventListeners = element => { return !!element.llEvLisnrs; }; - var addEventListeners = function addEventListeners(element, loadHandler, errorHandler) { + const addEventListeners = (element, loadHandler, errorHandler) => { if (!hasEventListeners(element)) element.llEvLisnrs = {}; - var loadEventName = element.tagName === "VIDEO" ? "loadeddata" : "load"; + const loadEventName = element.tagName === "VIDEO" ? "loadeddata" : "load"; addEventListener(element, loadEventName, loadHandler); addEventListener(element, "error", errorHandler); }; - var removeEventListeners = function removeEventListeners(element) { + const removeEventListeners = element => { if (!hasEventListeners(element)) { return; } - var eventListeners = element.llEvLisnrs; - for (var eventName in eventListeners) { - var handler = eventListeners[eventName]; + const eventListeners = element.llEvLisnrs; + for (let eventName in eventListeners) { + const handler = eventListeners[eventName]; removeEventListener(element, eventName, handler); } delete element.llEvLisnrs; }; - var doneHandler = function doneHandler(element, settings, instance) { + const doneHandler = (element, settings, instance) => { deleteTempImage(element); updateLoadingCount(instance, -1); decreaseToLoadCount(instance); @@ -455,16 +423,16 @@ unobserve(element, instance); } }; - var loadHandler = function loadHandler(event, element, settings, instance) { - var goingNative = hasStatusNative(element); + const loadHandler = (event, element, settings, instance) => { + const goingNative = hasStatusNative(element); doneHandler(element, settings, instance); addClass(element, settings.class_loaded); setStatus(element, statusLoaded); safeCallback(settings.callback_loaded, element, instance); if (!goingNative) checkFinish(settings, instance); }; - var errorHandler = function errorHandler(event, element, settings, instance) { - var goingNative = hasStatusNative(element); + const errorHandler = (event, element, settings, instance) => { + const goingNative = hasStatusNative(element); doneHandler(element, settings, instance); addClass(element, settings.class_error); setStatus(element, statusError); @@ -472,24 +440,24 @@ if (settings.restore_on_error) restoreOriginalAttrs(element, attrsSrcSrcsetSizes); if (!goingNative) checkFinish(settings, instance); }; - var addOneShotEventListeners = function addOneShotEventListeners(element, settings, instance) { - var elementToListenTo = getTempImage(element) || element; + const addOneShotEventListeners = (element, settings, instance) => { + const elementToListenTo = getTempImage(element) || element; if (hasEventListeners(elementToListenTo)) { // This happens when loading is retried twice return; } - var _loadHandler = function _loadHandler(event) { + const _loadHandler = event => { loadHandler(event, element, settings, instance); removeEventListeners(elementToListenTo); }; - var _errorHandler = function _errorHandler(event) { + const _errorHandler = event => { errorHandler(event, element, settings, instance); removeEventListeners(elementToListenTo); }; addEventListeners(elementToListenTo, _loadHandler, _errorHandler); }; - var loadBackground = function loadBackground(element, settings, instance) { + const loadBackground = (element, settings, instance) => { addTempImage(element); addOneShotEventListeners(element, settings, instance); saveOriginalBackgroundStyle(element); @@ -497,70 +465,70 @@ setMultiBackground(element, settings, instance); setImgsetBackground(element, settings, instance); }; - var loadRegular = function loadRegular(element, settings, instance) { + const loadRegular = (element, settings, instance) => { addOneShotEventListeners(element, settings, instance); setSources(element, settings, instance); }; - var load = function load(element, settings, instance) { + const load = (element, settings, instance) => { if (hasLoadEvent(element)) { loadRegular(element, settings, instance); } else { loadBackground(element, settings, instance); } }; - var loadNative = function loadNative(element, settings, instance) { + const loadNative = (element, settings, instance) => { element.setAttribute("loading", "lazy"); addOneShotEventListeners(element, settings, instance); setSourcesNative(element, settings); setStatus(element, statusNative); }; - var removeImageAttributes = function removeImageAttributes(element) { + const removeImageAttributes = element => { element.removeAttribute(SRC); element.removeAttribute(SRCSET); element.removeAttribute(SIZES); }; - var resetSourcesImg = function resetSourcesImg(element) { - forEachPictureSource(element, function (sourceTag) { + const resetSourcesImg = element => { + forEachPictureSource(element, sourceTag => { removeImageAttributes(sourceTag); }); removeImageAttributes(element); }; - var restoreImg = function restoreImg(imgEl) { - forEachPictureSource(imgEl, function (sourceEl) { + const restoreImg = imgEl => { + forEachPictureSource(imgEl, sourceEl => { restoreOriginalAttrs(sourceEl, attrsSrcSrcsetSizes); }); restoreOriginalAttrs(imgEl, attrsSrcSrcsetSizes); }; - var restoreVideo = function restoreVideo(videoEl) { - forEachVideoSource(videoEl, function (sourceEl) { + const restoreVideo = videoEl => { + forEachVideoSource(videoEl, sourceEl => { restoreOriginalAttrs(sourceEl, attrsSrc); }); restoreOriginalAttrs(videoEl, attrsSrcPoster); videoEl.load(); }; - var restoreIframe = function restoreIframe(iframeEl) { + const restoreIframe = iframeEl => { restoreOriginalAttrs(iframeEl, attrsSrc); }; - var restoreObject = function restoreObject(objectEl) { + const restoreObject = objectEl => { restoreOriginalAttrs(objectEl, attrsData); }; - var restoreFunctions = { + const restoreFunctions = { IMG: restoreImg, IFRAME: restoreIframe, VIDEO: restoreVideo, OBJECT: restoreObject }; - var restoreAttributes = function restoreAttributes(element) { - var restoreFunction = restoreFunctions[element.tagName]; + const restoreAttributes = element => { + const restoreFunction = restoreFunctions[element.tagName]; if (!restoreFunction) { restoreOriginalBgImage(element); return; } restoreFunction(element); }; - var resetClasses = function resetClasses(element, settings) { + const resetClasses = (element, settings) => { if (hasEmptyStatus(element) || hasStatusNative(element)) { return; } @@ -571,14 +539,14 @@ removeClass(element, settings.class_loaded); removeClass(element, settings.class_error); }; - var restore = function restore(element, settings) { + const restore = (element, settings) => { restoreAttributes(element); resetClasses(element, settings); resetStatus(element); deleteOriginalAttrs(element); }; - var cancelLoading = function cancelLoading(element, entry, settings, instance) { + const cancelLoading = (element, entry, settings, instance) => { if (!settings.cancel_on_exit) return; if (!hasStatusLoading(element)) return; if (element.tagName !== "IMG") return; //Works only on images @@ -591,9 +559,9 @@ safeCallback(settings.callback_cancel, element, entry, instance); }; - var onEnter = function onEnter(element, entry, settings, instance) { - var dontLoad = hadStartedLoading(element); /* Save status - before setting it, to prevent loading it again. Fixes #526. */ + const onEnter = (element, entry, settings, instance) => { + const dontLoad = hadStartedLoading(element); /* Save status + before setting it, to prevent loading it again. Fixes #526. */ setStatus(element, statusEntered); addClass(element, settings.class_entered); removeClass(element, settings.class_exited); @@ -602,19 +570,17 @@ if (dontLoad) return; load(element, settings, instance); }; - var onExit = function onExit(element, entry, settings, instance) { + const onExit = (element, entry, settings, instance) => { if (hasEmptyStatus(element)) return; //Ignore the first pass, at landing addClass(element, settings.class_exited); cancelLoading(element, entry, settings, instance); safeCallback(settings.callback_exit, element, entry, instance); }; - var tagsWithNativeLazy = ["IMG", "IFRAME", "VIDEO"]; - var shouldUseNative = function shouldUseNative(settings) { - return settings.use_native && "loading" in HTMLImageElement.prototype; - }; - var loadAllNative = function loadAllNative(elements, settings, instance) { - elements.forEach(function (element) { + const tagsWithNativeLazy = ["IMG", "IFRAME", "VIDEO"]; + const shouldUseNative = settings => settings.use_native && "loading" in HTMLImageElement.prototype; + const loadAllNative = (elements, settings, instance) => { + elements.forEach(element => { if (tagsWithNativeLazy.indexOf(element.tagName) === -1) { return; } @@ -623,83 +589,65 @@ setToLoadCount(instance, 0); }; - var isIntersecting = function isIntersecting(entry) { - return entry.isIntersecting || entry.intersectionRatio > 0; - }; - var getObserverSettings = function getObserverSettings(settings) { - return { - root: settings.container === document ? null : settings.container, - rootMargin: settings.thresholds || settings.threshold + "px" - }; - }; - var intersectionHandler = function intersectionHandler(entries, settings, instance) { - entries.forEach(function (entry) { - return isIntersecting(entry) ? onEnter(entry.target, entry, settings, instance) : onExit(entry.target, entry, settings, instance); - }); + const isIntersecting = entry => entry.isIntersecting || entry.intersectionRatio > 0; + const getObserverSettings = settings => ({ + root: settings.container === document ? null : settings.container, + rootMargin: settings.thresholds || settings.threshold + "px" + }); + const intersectionHandler = (entries, settings, instance) => { + entries.forEach(entry => isIntersecting(entry) ? onEnter(entry.target, entry, settings, instance) : onExit(entry.target, entry, settings, instance)); }; - var observeElements = function observeElements(observer, elements) { - elements.forEach(function (element) { + const observeElements = (observer, elements) => { + elements.forEach(element => { observer.observe(element); }); }; - var updateObserver = function updateObserver(observer, elementsToObserve) { + const updateObserver = (observer, elementsToObserve) => { resetObserver(observer); observeElements(observer, elementsToObserve); }; - var setObserver = function setObserver(settings, instance) { + const setObserver = (settings, instance) => { if (shouldUseNative(settings)) { return; } - instance._observer = new IntersectionObserver(function (entries) { + instance._observer = new IntersectionObserver(entries => { intersectionHandler(entries, settings, instance); }, getObserverSettings(settings)); }; - var toArray = function toArray(nodeSet) { - return Array.prototype.slice.call(nodeSet); - }; - var queryElements = function queryElements(settings) { - return settings.container.querySelectorAll(settings.elements_selector); - }; - var excludeManagedElements = function excludeManagedElements(elements) { - return toArray(elements).filter(hasEmptyStatus); - }; - var hasError = function hasError(element) { - return hasStatusError(element); - }; - var filterErrorElements = function filterErrorElements(elements) { - return toArray(elements).filter(hasError); - }; - var getElementsToLoad = function getElementsToLoad(elements, settings) { - return excludeManagedElements(elements || queryElements(settings)); - }; + const toArray = nodeSet => Array.prototype.slice.call(nodeSet); + const queryElements = settings => settings.container.querySelectorAll(settings.elements_selector); + const excludeManagedElements = elements => toArray(elements).filter(hasEmptyStatus); + const hasError = element => hasStatusError(element); + const filterErrorElements = elements => toArray(elements).filter(hasError); + const getElementsToLoad = (elements, settings) => excludeManagedElements(elements || queryElements(settings)); - var retryLazyLoad = function retryLazyLoad(settings, instance) { - var errorElements = filterErrorElements(queryElements(settings)); - errorElements.forEach(function (element) { + const retryLazyLoad = (settings, instance) => { + const errorElements = filterErrorElements(queryElements(settings)); + errorElements.forEach(element => { removeClass(element, settings.class_error); resetStatus(element); }); instance.update(); }; - var setOnlineCheck = function setOnlineCheck(settings, instance) { + const setOnlineCheck = (settings, instance) => { if (!runningOnBrowser) { return; } - instance._onlineHandler = function () { + instance._onlineHandler = () => { retryLazyLoad(settings, instance); }; window.addEventListener("online", instance._onlineHandler); }; - var resetOnlineCheck = function resetOnlineCheck(instance) { + const resetOnlineCheck = instance => { if (!runningOnBrowser) { return; } window.removeEventListener("online", instance._onlineHandler); }; - var LazyLoad = function LazyLoad(customSettings, elements) { - var settings = getExtendedSettings(customSettings); + const LazyLoad = function (customSettings, elements) { + const settings = getExtendedSettings(customSettings); this._settings = settings; this.loadingCount = 0; setObserver(settings, this); @@ -707,9 +655,9 @@ this.update(elements); }; LazyLoad.prototype = { - update: function update(givenNodeset) { - var settings = this._settings; - var elementsToLoad = getElementsToLoad(givenNodeset, settings); + update: function (givenNodeset) { + const settings = this._settings; + const elementsToLoad = getElementsToLoad(givenNodeset, settings); setToLoadCount(this, elementsToLoad.length); if (isBot) { this.loadAll(elementsToLoad); @@ -721,7 +669,7 @@ } updateObserver(this._observer, elementsToLoad); }, - destroy: function destroy() { + destroy: function () { // Observer if (this._observer) { this._observer.disconnect(); @@ -729,7 +677,7 @@ // Clean handlers resetOnlineCheck(this); // Clean custom attributes on elements - queryElements(this._settings).forEach(function (element) { + queryElements(this._settings).forEach(element => { deleteOriginalAttrs(element); }); // Delete all internal props @@ -739,27 +687,26 @@ delete this.loadingCount; delete this.toLoadCount; }, - loadAll: function loadAll(elements) { - var _this = this; - var settings = this._settings; - var elementsToLoad = getElementsToLoad(elements, settings); - elementsToLoad.forEach(function (element) { - unobserve(element, _this); - load(element, settings, _this); + loadAll: function (elements) { + const settings = this._settings; + const elementsToLoad = getElementsToLoad(elements, settings); + elementsToLoad.forEach(element => { + unobserve(element, this); + load(element, settings, this); }); }, - restoreAll: function restoreAll() { - var settings = this._settings; - queryElements(settings).forEach(function (element) { + restoreAll: function () { + const settings = this._settings; + queryElements(settings).forEach(element => { restore(element, settings); }); } }; - LazyLoad.load = function (element, customSettings) { - var settings = getExtendedSettings(customSettings); + LazyLoad.load = (element, customSettings) => { + const settings = getExtendedSettings(customSettings); load(element, settings); }; - LazyLoad.resetStatus = function (element) { + LazyLoad.resetStatus = element => { resetStatus(element); }; diff --git a/dist/lazyload.min.js b/dist/lazyload.min.js index c194c0f..15a0b42 100644 --- a/dist/lazyload.min.js +++ b/dist/lazyload.min.js @@ -1 +1 @@ -!function(n,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(n="undefined"!=typeof globalThis?globalThis:n||self).LazyLoad=t()}(this,(function(){"use strict";var n="undefined"!=typeof window,t=n&&!("onscroll"in window)||"undefined"!=typeof navigator&&/(gle|ing|ro)bot|crawl|spider/i.test(navigator.userAgent),e=n&&window.devicePixelRatio>1,i={elements_selector:".lazy",container:t||n?document:null,threshold:300,thresholds:null,data_src:"src",data_srcset:"srcset",data_sizes:"sizes",data_bg:"bg",data_bg_hidpi:"bg-hidpi",data_bg_multi:"bg-multi",data_bg_multi_hidpi:"bg-multi-hidpi",data_bg_set:"bg-set",data_poster:"poster",class_applied:"applied",class_loading:"loading",class_loaded:"loaded",class_error:"error",class_entered:"entered",class_exited:"exited",unobserve_completed:!0,unobserve_entered:!1,cancel_on_exit:!0,callback_enter:null,callback_exit:null,callback_applied:null,callback_loading:null,callback_loaded:null,callback_error:null,callback_finish:null,callback_cancel:null,use_native:!1,restore_on_error:!1},o=function(n){return Object.assign({},i,n)},a=function(n,t){var e,i="LazyLoad::Initialized",o=new n(t);try{e=new CustomEvent(i,{detail:{instance:o}})}catch(n){(e=document.createEvent("CustomEvent")).initCustomEvent(i,!1,!1,{instance:o})}window.dispatchEvent(e)},r="src",c="srcset",u="sizes",l="poster",s="llOriginalAttrs",d="data",f="loading",_="loaded",g="applied",v="error",b="native",h="data-",m="ll-status",p=function(n,t){return n.getAttribute(h+t)},E=function(n){return p(n,m)},I=function(n,t){return function(n,t,e){var i=h+t;null!==e?n.setAttribute(i,e):n.removeAttribute(i)}(n,m,t)},y=function(n){return I(n,null)},k=function(n){return null===E(n)},A=function(n){return E(n)===b},L=[f,_,g,v],w=function(n,t,e,i){n&&"function"==typeof n&&(void 0===i?void 0===e?n(t):n(t,e):n(t,e,i))},x=function(t,e){n&&""!==e&&t.classList.add(e)},C=function(t,e){n&&""!==e&&t.classList.remove(e)},O=function(n){return n.llTempImage},M=function(n,t){if(t){var e=t._observer;e&&e.unobserve(n)}},z=function(n,t){n&&(n.loadingCount+=t)},N=function(n,t){n&&(n.toLoadCount=t)},T=function(n){for(var t,e=[],i=0;t=n.children[i];i+=1)"SOURCE"===t.tagName&&e.push(t);return e},R=function(n,t){var e=n.parentNode;e&&"PICTURE"===e.tagName&&T(e).forEach(t)},G=function(n,t){T(n).forEach(t)},D=[r],H=[r,l],V=[r,c,u],F=[d],j=function(n){return!!n[s]},B=function(n){return n[s]},J=function(n){return delete n[s]},S=function(n,t){if(!j(n)){var e={};t.forEach((function(t){e[t]=n.getAttribute(t)})),n[s]=e}},P=function(n,t){if(j(n)){var e=B(n);t.forEach((function(t){!function(n,t,e){e?n.setAttribute(t,e):n.removeAttribute(t)}(n,t,e[t])}))}},U=function(n,t,e){x(n,t.class_applied),I(n,g),e&&(t.unobserve_completed&&M(n,t),w(t.callback_applied,n,e))},q=function(n,t,e){x(n,t.class_loading),I(n,f),e&&(z(e,1),w(t.callback_loading,n,e))},K=function(n,t,e){e&&n.setAttribute(t,e)},Q=function(n,t){K(n,u,p(n,t.data_sizes)),K(n,c,p(n,t.data_srcset)),K(n,r,p(n,t.data_src))},W={IMG:function(n,t){R(n,(function(n){S(n,V),Q(n,t)})),S(n,V),Q(n,t)},IFRAME:function(n,t){S(n,D),K(n,r,p(n,t.data_src))},VIDEO:function(n,t){G(n,(function(n){S(n,D),K(n,r,p(n,t.data_src))})),S(n,H),K(n,l,p(n,t.data_poster)),K(n,r,p(n,t.data_src)),n.load()},OBJECT:function(n,t){S(n,F),K(n,d,p(n,t.data_src))}},X=["IMG","IFRAME","VIDEO","OBJECT"],Y=function(n,t){!t||function(n){return n.loadingCount>0}(t)||function(n){return n.toLoadCount>0}(t)||w(n.callback_finish,t)},Z=function(n,t,e){n.addEventListener(t,e),n.llEvLisnrs[t]=e},$=function(n,t,e){n.removeEventListener(t,e)},nn=function(n){return!!n.llEvLisnrs},tn=function(n){if(nn(n)){var t=n.llEvLisnrs;for(var e in t){var i=t[e];$(n,e,i)}delete n.llEvLisnrs}},en=function(n,t,e){!function(n){delete n.llTempImage}(n),z(e,-1),function(n){n&&(n.toLoadCount-=1)}(e),C(n,t.class_loading),t.unobserve_completed&&M(n,e)},on=function(n,t,e){var i=O(n)||n;nn(i)||function(n,t,e){nn(n)||(n.llEvLisnrs={});var i="VIDEO"===n.tagName?"loadeddata":"load";Z(n,i,t),Z(n,"error",e)}(i,(function(o){!function(n,t,e,i){var o=A(t);en(t,e,i),x(t,e.class_loaded),I(t,_),w(e.callback_loaded,t,i),o||Y(e,i)}(0,n,t,e),tn(i)}),(function(o){!function(n,t,e,i){var o=A(t);en(t,e,i),x(t,e.class_error),I(t,v),w(e.callback_error,t,i),e.restore_on_error&&P(t,V),o||Y(e,i)}(0,n,t,e),tn(i)}))},an=function(n,t,i){!function(n){return X.indexOf(n.tagName)>-1}(n)?function(n,t,i){!function(n){n.llTempImage=document.createElement("IMG")}(n),on(n,t,i),function(n){j(n)||(n[s]={backgroundImage:n.style.backgroundImage})}(n),function(n,t,i){var o=p(n,t.data_bg),a=p(n,t.data_bg_hidpi),c=e&&a?a:o;c&&(n.style.backgroundImage='url("'.concat(c,'")'),O(n).setAttribute(r,c),q(n,t,i))}(n,t,i),function(n,t,i){var o=p(n,t.data_bg_multi),a=p(n,t.data_bg_multi_hidpi),r=e&&a?a:o;r&&(n.style.backgroundImage=r,U(n,t,i))}(n,t,i),function(n,t,e){var i=p(n,t.data_bg_set);if(i){var o=i.split("|").map((function(n){return"image-set(".concat(n,")")}));n.style.backgroundImage=o.join(),U(n,t,e)}}(n,t,i)}(n,t,i):function(n,t,e){on(n,t,e),function(n,t,e){var i=W[n.tagName];i&&(i(n,t),q(n,t,e))}(n,t,e)}(n,t,i)},rn=function(n){n.removeAttribute(r),n.removeAttribute(c),n.removeAttribute(u)},cn=function(n){R(n,(function(n){P(n,V)})),P(n,V)},un={IMG:cn,IFRAME:function(n){P(n,D)},VIDEO:function(n){G(n,(function(n){P(n,D)})),P(n,H),n.load()},OBJECT:function(n){P(n,F)}},ln=function(n,t){(function(n){var t=un[n.tagName];t?t(n):function(n){if(j(n)){var t=B(n);n.style.backgroundImage=t.backgroundImage}}(n)})(n),function(n,t){k(n)||A(n)||(C(n,t.class_entered),C(n,t.class_exited),C(n,t.class_applied),C(n,t.class_loading),C(n,t.class_loaded),C(n,t.class_error))}(n,t),y(n),J(n)},sn=["IMG","IFRAME","VIDEO"],dn=function(n){return n.use_native&&"loading"in HTMLImageElement.prototype},fn=function(n,t,e){n.forEach((function(n){return function(n){return n.isIntersecting||n.intersectionRatio>0}(n)?function(n,t,e,i){var o=function(n){return L.indexOf(E(n))>=0}(n);I(n,"entered"),x(n,e.class_entered),C(n,e.class_exited),function(n,t,e){t.unobserve_entered&&M(n,e)}(n,e,i),w(e.callback_enter,n,t,i),o||an(n,e,i)}(n.target,n,t,e):function(n,t,e,i){k(n)||(x(n,e.class_exited),function(n,t,e,i){e.cancel_on_exit&&function(n){return E(n)===f}(n)&&"IMG"===n.tagName&&(tn(n),function(n){R(n,(function(n){rn(n)})),rn(n)}(n),cn(n),C(n,e.class_loading),z(i,-1),y(n),w(e.callback_cancel,n,t,i))}(n,t,e,i),w(e.callback_exit,n,t,i))}(n.target,n,t,e)}))},_n=function(n){return Array.prototype.slice.call(n)},gn=function(n){return n.container.querySelectorAll(n.elements_selector)},vn=function(n){return function(n){return E(n)===v}(n)},bn=function(n,t){return function(n){return _n(n).filter(k)}(n||gn(t))},hn=function(t,e){var i=o(t);this._settings=i,this.loadingCount=0,function(n,t){dn(n)||(t._observer=new IntersectionObserver((function(e){fn(e,n,t)}),function(n){return{root:n.container===document?null:n.container,rootMargin:n.thresholds||n.threshold+"px"}}(n)))}(i,this),function(t,e){n&&(e._onlineHandler=function(){!function(n,t){var e;(e=gn(n),_n(e).filter(vn)).forEach((function(t){C(t,n.class_error),y(t)})),t.update()}(t,e)},window.addEventListener("online",e._onlineHandler))}(i,this),this.update(e)};return hn.prototype={update:function(n){var e,i,o=this._settings,a=bn(n,o);N(this,a.length),t?this.loadAll(a):dn(o)?function(n,t,e){n.forEach((function(n){-1!==sn.indexOf(n.tagName)&&function(n,t,e){n.setAttribute("loading","lazy"),on(n,t,e),function(n,t){var e=W[n.tagName];e&&e(n,t)}(n,t),I(n,b)}(n,t,e)})),N(e,0)}(a,o,this):(i=a,function(n){n.disconnect()}(e=this._observer),function(n,t){t.forEach((function(t){n.observe(t)}))}(e,i))},destroy:function(){this._observer&&this._observer.disconnect(),n&&window.removeEventListener("online",this._onlineHandler),gn(this._settings).forEach((function(n){J(n)})),delete this._observer,delete this._settings,delete this._onlineHandler,delete this.loadingCount,delete this.toLoadCount},loadAll:function(n){var t=this,e=this._settings;bn(n,e).forEach((function(n){M(n,t),an(n,e,t)}))},restoreAll:function(){var n=this._settings;gn(n).forEach((function(t){ln(t,n)}))}},hn.load=function(n,t){var e=o(t);an(n,e)},hn.resetStatus=function(n){y(n)},n&&function(n,t){if(t)if(t.length)for(var e,i=0;e=t[i];i+=1)a(n,e);else a(n,t)}(hn,window.lazyLoadOptions),hn})); +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).LazyLoad=t()}(this,(function(){"use strict";const e="undefined"!=typeof window,t=e&&!("onscroll"in window)||"undefined"!=typeof navigator&&/(gle|ing|ro)bot|crawl|spider/i.test(navigator.userAgent),a=e&&window.devicePixelRatio>1,n={elements_selector:".lazy",container:t||e?document:null,threshold:300,thresholds:null,data_src:"src",data_srcset:"srcset",data_sizes:"sizes",data_bg:"bg",data_bg_hidpi:"bg-hidpi",data_bg_multi:"bg-multi",data_bg_multi_hidpi:"bg-multi-hidpi",data_bg_set:"bg-set",data_poster:"poster",class_applied:"applied",class_loading:"loading",class_loaded:"loaded",class_error:"error",class_entered:"entered",class_exited:"exited",unobserve_completed:!0,unobserve_entered:!1,cancel_on_exit:!0,callback_enter:null,callback_exit:null,callback_applied:null,callback_loading:null,callback_loaded:null,callback_error:null,callback_finish:null,callback_cancel:null,use_native:!1,restore_on_error:!1},s=e=>Object.assign({},n,e),l=function(e,t){let a;const n="LazyLoad::Initialized",s=new e(t);try{a=new CustomEvent(n,{detail:{instance:s}})}catch(e){a=document.createEvent("CustomEvent"),a.initCustomEvent(n,!1,!1,{instance:s})}window.dispatchEvent(a)},o="src",r="srcset",i="sizes",d="poster",c="llOriginalAttrs",_="data",u="loading",g="loaded",b="applied",h="error",m="native",p="data-",f="ll-status",v=(e,t)=>e.getAttribute(p+t),E=e=>v(e,f),I=(e,t)=>((e,t,a)=>{const n=p+t;null!==a?e.setAttribute(n,a):e.removeAttribute(n)})(e,f,t),y=e=>I(e,null),k=e=>null===E(e),A=e=>E(e)===m,L=[u,g,b,h],w=(e,t,a,n)=>{e&&"function"==typeof e&&(void 0===n?void 0===a?e(t):e(t,a):e(t,a,n))},x=(t,a)=>{e&&""!==a&&t.classList.add(a)},C=(t,a)=>{e&&""!==a&&t.classList.remove(a)},O=e=>e.llTempImage,M=(e,t)=>{if(!t)return;const a=t._observer;a&&a.unobserve(e)},z=(e,t)=>{e&&(e.loadingCount+=t)},N=(e,t)=>{e&&(e.toLoadCount=t)},T=e=>{let t=[];for(let a,n=0;a=e.children[n];n+=1)"SOURCE"===a.tagName&&t.push(a);return t},R=(e,t)=>{const a=e.parentNode;a&&"PICTURE"===a.tagName&&T(a).forEach(t)},G=(e,t)=>{T(e).forEach(t)},D=[o],H=[o,d],V=[o,r,i],F=[_],j=e=>!!e[c],B=e=>e[c],J=e=>delete e[c],S=(e,t)=>{if(j(e))return;const a={};t.forEach((t=>{a[t]=e.getAttribute(t)})),e[c]=a},P=(e,t)=>{if(!j(e))return;const a=B(e);t.forEach((t=>{((e,t,a)=>{a?e.setAttribute(t,a):e.removeAttribute(t)})(e,t,a[t])}))},U=(e,t,a)=>{x(e,t.class_applied),I(e,b),a&&(t.unobserve_completed&&M(e,t),w(t.callback_applied,e,a))},$=(e,t,a)=>{x(e,t.class_loading),I(e,u),a&&(z(a,1),w(t.callback_loading,e,a))},q=(e,t,a)=>{a&&e.setAttribute(t,a)},K=(e,t)=>{q(e,i,v(e,t.data_sizes)),q(e,r,v(e,t.data_srcset)),q(e,o,v(e,t.data_src))},Q={IMG:(e,t)=>{R(e,(e=>{S(e,V),K(e,t)})),S(e,V),K(e,t)},IFRAME:(e,t)=>{S(e,D),q(e,o,v(e,t.data_src))},VIDEO:(e,t)=>{G(e,(e=>{S(e,D),q(e,o,v(e,t.data_src))})),S(e,H),q(e,d,v(e,t.data_poster)),q(e,o,v(e,t.data_src)),e.load()},OBJECT:(e,t)=>{S(e,F),q(e,_,v(e,t.data_src))}},W=["IMG","IFRAME","VIDEO","OBJECT"],X=(e,t)=>{!t||(e=>e.loadingCount>0)(t)||(e=>e.toLoadCount>0)(t)||w(e.callback_finish,t)},Y=(e,t,a)=>{e.addEventListener(t,a),e.llEvLisnrs[t]=a},Z=(e,t,a)=>{e.removeEventListener(t,a)},ee=e=>!!e.llEvLisnrs,te=e=>{if(!ee(e))return;const t=e.llEvLisnrs;for(let a in t){const n=t[a];Z(e,a,n)}delete e.llEvLisnrs},ae=(e,t,a)=>{(e=>{delete e.llTempImage})(e),z(a,-1),(e=>{e&&(e.toLoadCount-=1)})(a),C(e,t.class_loading),t.unobserve_completed&&M(e,a)},ne=(e,t,a)=>{const n=O(e)||e;ee(n)||((e,t,a)=>{ee(e)||(e.llEvLisnrs={});const n="VIDEO"===e.tagName?"loadeddata":"load";Y(e,n,t),Y(e,"error",a)})(n,(s=>{((e,t,a,n)=>{const s=A(t);ae(t,a,n),x(t,a.class_loaded),I(t,g),w(a.callback_loaded,t,n),s||X(a,n)})(0,e,t,a),te(n)}),(s=>{((e,t,a,n)=>{const s=A(t);ae(t,a,n),x(t,a.class_error),I(t,h),w(a.callback_error,t,n),a.restore_on_error&&P(t,V),s||X(a,n)})(0,e,t,a),te(n)}))},se=(e,t,n)=>{(e=>W.indexOf(e.tagName)>-1)(e)?((e,t,a)=>{ne(e,t,a),((e,t,a)=>{const n=Q[e.tagName];n&&(n(e,t),$(e,t,a))})(e,t,a)})(e,t,n):((e,t,n)=>{(e=>{e.llTempImage=document.createElement("IMG")})(e),ne(e,t,n),(e=>{j(e)||(e[c]={backgroundImage:e.style.backgroundImage})})(e),((e,t,n)=>{const s=v(e,t.data_bg),l=v(e,t.data_bg_hidpi),r=a&&l?l:s;r&&(e.style.backgroundImage=`url("${r}")`,O(e).setAttribute(o,r),$(e,t,n))})(e,t,n),((e,t,n)=>{const s=v(e,t.data_bg_multi),l=v(e,t.data_bg_multi_hidpi),o=a&&l?l:s;o&&(e.style.backgroundImage=o,U(e,t,n))})(e,t,n),((e,t,a)=>{const n=v(e,t.data_bg_set);if(!n)return;let s=n.split("|").map((e=>`image-set(${e})`));e.style.backgroundImage=s.join(),U(e,t,a)})(e,t,n)})(e,t,n)},le=e=>{e.removeAttribute(o),e.removeAttribute(r),e.removeAttribute(i)},oe=e=>{R(e,(e=>{P(e,V)})),P(e,V)},re={IMG:oe,IFRAME:e=>{P(e,D)},VIDEO:e=>{G(e,(e=>{P(e,D)})),P(e,H),e.load()},OBJECT:e=>{P(e,F)}},ie=(e,t)=>{(e=>{const t=re[e.tagName];t?t(e):(e=>{if(!j(e))return;const t=B(e);e.style.backgroundImage=t.backgroundImage})(e)})(e),((e,t)=>{k(e)||A(e)||(C(e,t.class_entered),C(e,t.class_exited),C(e,t.class_applied),C(e,t.class_loading),C(e,t.class_loaded),C(e,t.class_error))})(e,t),y(e),J(e)},de=["IMG","IFRAME","VIDEO"],ce=e=>e.use_native&&"loading"in HTMLImageElement.prototype,_e=(e,t,a)=>{e.forEach((e=>(e=>e.isIntersecting||e.intersectionRatio>0)(e)?((e,t,a,n)=>{const s=(e=>L.indexOf(E(e))>=0)(e);I(e,"entered"),x(e,a.class_entered),C(e,a.class_exited),((e,t,a)=>{t.unobserve_entered&&M(e,a)})(e,a,n),w(a.callback_enter,e,t,n),s||se(e,a,n)})(e.target,e,t,a):((e,t,a,n)=>{k(e)||(x(e,a.class_exited),((e,t,a,n)=>{a.cancel_on_exit&&(e=>E(e)===u)(e)&&"IMG"===e.tagName&&(te(e),(e=>{R(e,(e=>{le(e)})),le(e)})(e),oe(e),C(e,a.class_loading),z(n,-1),y(e),w(a.callback_cancel,e,t,n))})(e,t,a,n),w(a.callback_exit,e,t,n))})(e.target,e,t,a)))},ue=e=>Array.prototype.slice.call(e),ge=e=>e.container.querySelectorAll(e.elements_selector),be=e=>(e=>E(e)===h)(e),he=(e,t)=>(e=>ue(e).filter(k))(e||ge(t)),me=function(t,a){const n=s(t);this._settings=n,this.loadingCount=0,((e,t)=>{ce(e)||(t._observer=new IntersectionObserver((a=>{_e(a,e,t)}),(e=>({root:e.container===document?null:e.container,rootMargin:e.thresholds||e.threshold+"px"}))(e)))})(n,this),((t,a)=>{e&&(a._onlineHandler=()=>{((e,t)=>{var a;(a=ge(e),ue(a).filter(be)).forEach((t=>{C(t,e.class_error),y(t)})),t.update()})(t,a)},window.addEventListener("online",a._onlineHandler))})(n,this),this.update(a)};return me.prototype={update:function(e){const a=this._settings,n=he(e,a);var s,l;N(this,n.length),t?this.loadAll(n):ce(a)?((e,t,a)=>{e.forEach((e=>{-1!==de.indexOf(e.tagName)&&((e,t,a)=>{e.setAttribute("loading","lazy"),ne(e,t,a),((e,t)=>{const a=Q[e.tagName];a&&a(e,t)})(e,t),I(e,m)})(e,t,a)})),N(a,0)})(n,a,this):(l=n,(e=>{e.disconnect()})(s=this._observer),((e,t)=>{t.forEach((t=>{e.observe(t)}))})(s,l))},destroy:function(){this._observer&&this._observer.disconnect(),e&&window.removeEventListener("online",this._onlineHandler),ge(this._settings).forEach((e=>{J(e)})),delete this._observer,delete this._settings,delete this._onlineHandler,delete this.loadingCount,delete this.toLoadCount},loadAll:function(e){const t=this._settings;he(e,t).forEach((e=>{M(e,this),se(e,t,this)}))},restoreAll:function(){const e=this._settings;ge(e).forEach((t=>{ie(t,e)}))}},me.load=(e,t)=>{const a=s(t);se(e,a)},me.resetStatus=e=>{y(e)},e&&((e,t)=>{if(t)if(t.length)for(let a,n=0;a=t[n];n+=1)l(e,a);else l(e,t)})(me,window.lazyLoadOptions),me})); diff --git a/package-lock.json b/package-lock.json index 0f7355c..24e4d96 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "vanilla-lazyload", - "version": "19.1.1", + "version": "19.1.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "vanilla-lazyload", - "version": "19.1.1", + "version": "19.1.2", "license": "MIT", "devDependencies": { "@babel/core": "^7.24.3", diff --git a/package.json b/package.json index 1408d22..9eb2607 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vanilla-lazyload", - "version": "19.1.1", + "version": "19.1.2", "description": "LazyLoad is a lightweight (2.4 kB) and flexible script that speeds up your web application by deferring the loading of your below-the-fold images, videos and iframes to when they will enter the viewport. It's written in plain \"vanilla\" JavaScript, it leverages the IntersectionObserver API, it supports responsive images, it optimizes your website for slower connections, and can enable native lazy loading.", "main": "dist/lazyload.min.js", "module": "dist/esm/lazyload.js",