vanilla-lazyload
Advanced tools
Comparing version 15.2.0 to 16.0.0
# CHANGELOG | ||
## Version 16 | ||
Functional changes: | ||
- Removed call to deprecated `callback_reveal` | ||
- Removed deprecated instance `load()` method in favor of the static `LazyLoad.load()` method | ||
- Replaced `auto_unobserve` with `unobserve_completed`, still defaulting to `true` | ||
- Introduced a new `unobserve_entered` option (useful to execute lazy functions once) | ||
- Created a demo called `lazy_functions.html` to show how to execute functions as elements enter the viewport | ||
- Wrote a new recipe to facilitate the lazy execution of scripts/functions | ||
- Renamed instance method `resetElementStatus()` to the static `LazyLoad.resetStatus()` | ||
- Removed the `load_delay` option since there's no more use for it | ||
- Removed the `load_delay` related demos | ||
See [UPGRADE.md](UPGRADE.md) to understand **if** you are impacted by any breaking change and **how** to upgrade from previous versions. | ||
Internal changes: | ||
- Simplified management of the `cancel_on_exit` with less increase/decrease of the `toLoadCount` property | ||
- Refactored counters functions in a new `lazyload.counters` file | ||
--- | ||
**Love this project? 😍 [Buy me a coffee!](https://ko-fi.com/verlok)** | ||
--- | ||
## Version 15 | ||
@@ -4,0 +31,0 @@ |
@@ -44,4 +44,4 @@ define(function () { 'use strict'; | ||
class_error: "error", | ||
load_delay: 0, | ||
auto_unobserve: true, | ||
unobserve_completed: true, | ||
unobserve_entered: false, | ||
cancel_on_exit: false, | ||
@@ -105,3 +105,2 @@ callback_enter: null, | ||
var statusDelayed = "delayed"; | ||
var statusLoading = "loading"; | ||
@@ -115,3 +114,2 @@ var statusLoaded = "loaded"; | ||
var statusDataName = "ll-status"; | ||
var timeoutDataName = "ll-timeout"; | ||
var getData = function getData(element, attribute) { | ||
@@ -148,5 +146,2 @@ return element.getAttribute(dataPrefix + attribute); | ||
}; | ||
var hasStatusDelayed = function hasStatusDelayed(element) { | ||
return getStatus(element) === statusDelayed; | ||
}; | ||
var statusesAfterLoading = [statusLoading, statusApplied, statusLoaded, statusError]; | ||
@@ -156,8 +151,2 @@ var hasStatusAfterLoading = function hasStatusAfterLoading(element) { | ||
}; | ||
var setTimeoutData = function setTimeoutData(element, value) { | ||
return setData(element, timeoutDataName, value); | ||
}; | ||
var getTimeoutData = function getTimeoutData(element) { | ||
return getData(element, timeoutDataName); | ||
}; | ||
@@ -209,6 +198,6 @@ var safeCallback = function safeCallback(callback, arg1, arg2, arg3) { | ||
var unobserve = function unobserve(element, settings, instance) { | ||
var unobserve = function unobserve(element, instance) { | ||
if (!instance) return; | ||
var observer = instance._observer; | ||
if (!observer || !settings.auto_unobserve) return; | ||
if (!observer) return; | ||
observer.unobserve(element); | ||
@@ -220,2 +209,21 @@ }; | ||
var updateLoadingCount = function updateLoadingCount(instance, delta) { | ||
if (!instance) return; | ||
instance.loadingCount += delta; | ||
}; | ||
var decreaseToLoadCount = function decreaseToLoadCount(instance) { | ||
if (!instance) return; | ||
instance.toLoadCount -= 1; | ||
}; | ||
var setToLoadCount = function 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; | ||
}; | ||
var _src_ = "src"; | ||
@@ -226,6 +234,2 @@ var _srcset_ = "srcset"; | ||
var _PICTURE_ = "PICTURE"; | ||
var increaseLoadingCount = function increaseLoadingCount(instance) { | ||
if (!instance) return; | ||
instance.loadingCount += 1; | ||
}; | ||
var getSourceTags = function getSourceTags(parentTag) { | ||
@@ -256,3 +260,6 @@ var sourceTags = []; | ||
var saveOriginalImageAttributes = function saveOriginalImageAttributes(element) { | ||
if (hasOriginalAttributes(element)) return; | ||
if (hasOriginalAttributes(element)) { | ||
return; | ||
} | ||
var originalAttributes = {}; | ||
@@ -265,3 +272,6 @@ originalAttributes[_src_] = element.getAttribute(_src_); | ||
var restoreOriginalImageAttributes = function restoreOriginalImageAttributes(element) { | ||
if (!hasOriginalAttributes(element)) return; | ||
if (!hasOriginalAttributes(element)) { | ||
return; | ||
} | ||
var originalAttributes = element.llOriginalAttrs; | ||
@@ -284,3 +294,7 @@ setAttributeIfValue(element, _src_, originalAttributes[_src_]); | ||
var parent = element.parentNode; | ||
if (!parent || parent.tagName !== _PICTURE_) return; | ||
if (!parent || parent.tagName !== _PICTURE_) { | ||
return; | ||
} | ||
var sourceTags = getSourceTags(parent); | ||
@@ -334,7 +348,6 @@ sourceTags.forEach(fn); | ||
increaseLoadingCount(instance); | ||
updateLoadingCount(instance, +1); | ||
addClass(element, settings.class_loading); | ||
setStatus(element, statusLoading); | ||
safeCallback(settings.callback_loading, element, instance); | ||
safeCallback(settings.callback_reveal, element, instance); // <== DEPRECATED | ||
}; // NOTE: THE TEMP IMAGE TRICK CANNOT BE DONE WITH data-multi-bg | ||
@@ -348,3 +361,7 @@ // BECAUSE INSIDE ITS VALUES MUST BE WRAPPED WITH URL() AND ONE OF THEM | ||
var bgDataValue = isHiDpi && bgHiDpiValue ? bgHiDpiValue : bg1xValue; | ||
if (!bgDataValue) return; | ||
if (!bgDataValue) { | ||
return; | ||
} | ||
element.style.backgroundImage = bgDataValue; // Annotate and notify applied | ||
@@ -354,16 +371,22 @@ | ||
setStatus(element, statusApplied); | ||
unobserve(element, settings, instance); // Unobserve here because we can't do it on load | ||
safeCallback(settings.callback_applied, element, instance); | ||
safeCallback(settings.callback_applied, element, instance); | ||
if (settings.unobserve_completed) { | ||
// Unobserve now because we can't do it on load | ||
unobserve(element, settings); | ||
} | ||
}; | ||
var setSources = function setSources(element, settings, instance) { | ||
var setSourcesFunction = setSourcesFunctions[element.tagName]; | ||
if (!setSourcesFunction) return; | ||
if (!setSourcesFunction) { | ||
return; | ||
} | ||
setSourcesFunction(element, settings); // Annotate and notify loading | ||
increaseLoadingCount(instance); | ||
updateLoadingCount(instance, +1); | ||
addClass(element, settings.class_loading); | ||
setStatus(element, statusLoading); | ||
safeCallback(settings.callback_loading, element, instance); | ||
safeCallback(settings.callback_reveal, element, instance); // <== DEPRECATED | ||
}; | ||
@@ -378,9 +401,6 @@ | ||
}; | ||
var decreaseLoadingCount = function decreaseLoadingCount(instance) { | ||
if (!instance) return; | ||
instance.loadingCount -= 1; | ||
}; | ||
var checkFinish = function checkFinish(settings, instance) { | ||
if (!instance || instance.toLoadCount || instance.loadingCount) return; | ||
safeCallback(settings.callback_finish, instance); | ||
if (instance && !isSomethingLoading(instance) && !haveElementsToLoad(instance)) { | ||
safeCallback(settings.callback_finish, instance); | ||
} | ||
}; | ||
@@ -401,7 +421,12 @@ var addEventListener = function addEventListener(element, eventName, handler) { | ||
addEventListener(element, errorEventName, errorHandler); | ||
if (element.tagName !== "VIDEO") return; | ||
addEventListener(element, mediaLoadEventName, loadHandler); | ||
if (element.tagName === "VIDEO") { | ||
addEventListener(element, mediaLoadEventName, loadHandler); | ||
} | ||
}; | ||
var removeEventListeners = function removeEventListeners(element) { | ||
if (!hasEventListeners(element)) return; | ||
if (!hasEventListeners(element)) { | ||
return; | ||
} | ||
var eventListeners = element.llEvLisnrs; | ||
@@ -418,5 +443,9 @@ | ||
deleteTempImage(element); | ||
decreaseLoadingCount(instance); | ||
updateLoadingCount(instance, -1); | ||
decreaseToLoadCount(instance); | ||
removeClass(element, settings.class_loading); | ||
unobserve(element, settings, instance); | ||
if (settings.unobserve_completed) { | ||
unobserve(element, instance); | ||
} | ||
}; | ||
@@ -439,4 +468,8 @@ var loadHandler = function loadHandler(event, element, settings, instance) { | ||
var elementToListenTo = getTempImage(element) || element; | ||
if (hasEventListeners(elementToListenTo)) return; // <- when retry loading, e.g. with cancel_on_exit | ||
if (hasEventListeners(elementToListenTo)) { | ||
// This happens when loading is retried twice | ||
return; | ||
} | ||
var _loadHandler = function _loadHandler(event) { | ||
@@ -455,11 +488,2 @@ loadHandler(event, element, settings, instance); | ||
var decreaseToLoadCount = function decreaseToLoadCount(instance) { | ||
if (!instance) return; | ||
instance.toLoadCount -= 1; | ||
}; | ||
var increaseToLoadCount = function increaseToLoadCount(instance) { | ||
if (!instance) return; | ||
instance.toLoadCount += 1; | ||
}; | ||
var loadBackground = function loadBackground(element, settings, instance) { | ||
@@ -484,3 +508,2 @@ addTempImage(element); | ||
decreaseToLoadCount(instance); | ||
checkFinish(settings, instance); | ||
@@ -491,3 +514,2 @@ }; | ||
setSources(element, settings, instance); | ||
decreaseToLoadCount(instance); | ||
setStatus(element, statusNative); | ||
@@ -497,35 +519,8 @@ checkFinish(settings, instance); | ||
var cancelDelayLoad = function cancelDelayLoad(element) { | ||
var timeoutId = getTimeoutData(element); | ||
if (!timeoutId) { | ||
return; // do nothing if timeout doesn't exist | ||
var cancelIfLoading = function cancelIfLoading(element, entry, settings, instance) { | ||
if (element.tagName !== "IMG") { | ||
// Can't cancel loading on anything but images | ||
return; | ||
} | ||
if (hasStatusDelayed(element)) { | ||
// iffing because status could also be "loading" | ||
resetStatus(element); | ||
} | ||
clearTimeout(timeoutId); | ||
setTimeoutData(element, null); | ||
}; | ||
var delayLoad = function delayLoad(element, settings, instance) { | ||
var loadDelay = settings.load_delay; | ||
var timeoutId = getTimeoutData(element); | ||
if (timeoutId) { | ||
return; // do nothing if timeout already set | ||
} | ||
timeoutId = setTimeout(function () { | ||
load(element, settings, instance); | ||
cancelDelayLoad(element); | ||
}, loadDelay); | ||
setStatus(element, statusDelayed); | ||
setTimeoutData(element, timeoutId); | ||
}; | ||
var cancelIfLoading = function cancelIfLoading(element, entry, settings, instance) { | ||
if (element.tagName !== "IMG") return; | ||
removeEventListeners(element); | ||
@@ -535,3 +530,3 @@ resetSourcesImg(element); | ||
removeClass(element, settings.class_loading); | ||
decreaseLoadingCount(instance); | ||
updateLoadingCount(instance, -1); | ||
safeCallback(settings.callback_cancel, element, entry, instance); // setTimeout is needed because the "callback_cancel" implementation | ||
@@ -541,19 +536,23 @@ // could be out of the main thread, e.g. `img.setAttribute("src", "")` | ||
setTimeout(function () { | ||
instance.resetElementStatus(element, instance); | ||
resetStatus(element); | ||
}, 0); | ||
}; | ||
var onIntersecting = function onIntersecting(element, entry, settings, instance) { | ||
var onEnter = function onEnter(element, entry, settings, instance) { | ||
safeCallback(settings.callback_enter, element, entry, instance); | ||
if (hasStatusAfterLoading(element)) return; //Prevent loading it again, e.g. on !auto_unobserve | ||
if (settings.load_delay) { | ||
delayLoad(element, settings, instance); | ||
return; | ||
if (hasStatusAfterLoading(element)) { | ||
return; //Prevent loading it again | ||
} | ||
if (settings.unobserve_entered) { | ||
unobserve(element, instance); | ||
} | ||
load(element, settings, instance); | ||
}; | ||
var onNotIntersecting = function onNotIntersecting(element, entry, settings, instance) { | ||
if (hasEmptyStatus(element)) return; //Ignore the first pass at landing | ||
var onExit = function onExit(element, entry, settings, instance) { | ||
if (hasEmptyStatus(element)) { | ||
return; //Ignore the first pass, at landing | ||
} | ||
@@ -565,6 +564,2 @@ if (settings.cancel_on_exit && hasStatusLoading(element)) { | ||
safeCallback(settings.callback_exit, element, entry, instance); | ||
if (settings.load_delay && hasStatusDelayed(element)) { | ||
cancelDelayLoad(element); | ||
} | ||
}; | ||
@@ -587,3 +582,3 @@ | ||
}); | ||
instance.toLoadCount = 0; | ||
setToLoadCount(instance, 0); | ||
}; | ||
@@ -604,3 +599,3 @@ | ||
entries.forEach(function (entry) { | ||
return isIntersecting(entry) ? onIntersecting(entry.target, entry, settings, instance) : onNotIntersecting(entry.target, entry, settings, instance); | ||
return isIntersecting(entry) ? onEnter(entry.target, entry, settings, instance) : onExit(entry.target, entry, settings, instance); | ||
}); | ||
@@ -618,6 +613,4 @@ }; | ||
}; | ||
var setObserver = function setObserver(instance) { | ||
var settings = instance._settings; | ||
if (!supportsIntersectionObserver || shouldUseNative(instance._settings)) { | ||
var setObserver = function setObserver(settings, instance) { | ||
if (!supportsIntersectionObserver || shouldUseNative(settings)) { | ||
return; | ||
@@ -650,4 +643,3 @@ } | ||
var retryLazyLoad = function retryLazyLoad(instance) { | ||
var settings = instance._settings; | ||
var retryLazyLoad = function retryLazyLoad(settings, instance) { | ||
var errorElements = filterErrorElements(queryElements(settings)); | ||
@@ -660,3 +652,3 @@ errorElements.forEach(function (element) { | ||
}; | ||
var setOnlineCheck = function setOnlineCheck(instance) { | ||
var setOnlineCheck = function setOnlineCheck(settings, instance) { | ||
if (!runningOnBrowser) { | ||
@@ -666,20 +658,13 @@ return; | ||
window.addEventListener("online", function (event) { | ||
retryLazyLoad(instance); | ||
window.addEventListener("online", function () { | ||
retryLazyLoad(settings, instance); | ||
}); | ||
}; | ||
var resetElementStatus = function resetElementStatus(element, instance) { | ||
if (hasStatusAfterLoading(element)) { | ||
increaseToLoadCount(instance); | ||
} | ||
setStatus(element, null); | ||
}; | ||
var LazyLoad = function LazyLoad(customSettings, elements) { | ||
this._settings = getExtendedSettings(customSettings); | ||
var settings = getExtendedSettings(customSettings); | ||
this._settings = settings; | ||
this.loadingCount = 0; | ||
setObserver(this); | ||
setOnlineCheck(this); | ||
setObserver(settings, this); | ||
setOnlineCheck(settings, this); | ||
this.update(elements); | ||
@@ -692,3 +677,3 @@ }; | ||
var elementsToLoad = getElementsToLoad(givenNodeset, settings); | ||
this.toLoadCount = elementsToLoad.length; | ||
setToLoadCount(this, elementsToLoad.length); | ||
@@ -726,9 +711,2 @@ if (isBot || !supportsIntersectionObserver) { | ||
}); | ||
}, | ||
resetElementStatus: function resetElementStatus$1(element) { | ||
resetElementStatus(element, this); | ||
}, | ||
// DEPRECATED | ||
load: function load$1(element) { | ||
load(element, this._settings, this); | ||
} | ||
@@ -739,4 +717,7 @@ }; | ||
var settings = getExtendedSettings(customSettings); | ||
load(element, settings); | ||
}; | ||
load(element, settings); | ||
LazyLoad.resetStatus = function (element) { | ||
resetStatus(element); | ||
}; // Automatic instances creation if required (useful for async script loading) | ||
@@ -743,0 +724,0 @@ |
@@ -1,1 +0,1 @@ | ||
define((function(){"use strict";function t(){return(t=Object.assign||function(t){for(var n=1;n<arguments.length;n++){var e=arguments[n];for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])}return t}).apply(this,arguments)}var n="undefined"!=typeof window,e=n&&!("onscroll"in window)||"undefined"!=typeof navigator&&/(gle|ing|ro)bot|crawl|spider/i.test(navigator.userAgent),i=n&&"IntersectionObserver"in window,a=n&&"classList"in document.createElement("p"),o=n&&window.devicePixelRatio>1,r={elements_selector:"img",container:e||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_poster:"poster",class_applied:"applied",class_loading:"loading",class_loaded:"loaded",class_error:"error",load_delay:0,auto_unobserve:!0,cancel_on_exit:!1,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},c=function(n){return t({},r,n)},l=function(t,n){var e,i=new t(n);try{e=new CustomEvent("LazyLoad::Initialized",{detail:{instance:i}})}catch(t){(e=document.createEvent("CustomEvent")).initCustomEvent("LazyLoad::Initialized",!1,!1,{instance:i})}window.dispatchEvent(e)},s=function(t,n){return t.getAttribute("data-"+n)},u=function(t,n,e){var i="data-"+n;null!==e?t.setAttribute(i,e):t.removeAttribute(i)},d=function(t){return s(t,"ll-status")},f=function(t,n){return u(t,"ll-status",n)},_=function(t){return f(t,null)},g=function(t){return null===d(t)},v=function(t){return"delayed"===d(t)},b=["loading","applied","loaded","error"],p=function(t){return b.indexOf(d(t))>-1},h=function(t,n){return u(t,"ll-timeout",n)},m=function(t){return s(t,"ll-timeout")},E=function(t,n,e,i){t&&(void 0===i?void 0===e?t(n):t(n,e):t(n,e,i))},y=function(t,n){a?t.classList.add(n):t.className+=(t.className?" ":"")+n},L=function(t,n){a?t.classList.remove(n):t.className=t.className.replace(new RegExp("(^|\\s+)"+n+"(\\s+|$)")," ").replace(/^\s+/,"").replace(/\s+$/,"")},I=function(t){return t.llTempImage},k=function(t,n,e){if(e){var i=e._observer;i&&n.auto_unobserve&&i.unobserve(t)}},A=function(t){t&&(t.loadingCount+=1)},w=function(t){for(var n,e=[],i=0;n=t.children[i];i+=1)"SOURCE"===n.tagName&&e.push(n);return e},C=function(t,n,e){e&&t.setAttribute(n,e)},O=function(t,n){t.removeAttribute(n)},z=function(t){return!!t.llOriginalAttrs},N=function(t){if(!z(t)){var n={};n.src=t.getAttribute("src"),n.srcset=t.getAttribute("srcset"),n.sizes=t.getAttribute("sizes"),t.llOriginalAttrs=n}},x=function(t){if(z(t)){var n=t.llOriginalAttrs;C(t,"src",n.src),C(t,"srcset",n.srcset),C(t,"sizes",n.sizes)}},M=function(t,n){C(t,"sizes",s(t,n.data_sizes)),C(t,"srcset",s(t,n.data_srcset)),C(t,"src",s(t,n.data_src))},R=function(t){O(t,"src"),O(t,"srcset"),O(t,"sizes")},T=function(t,n){var e=t.parentNode;e&&"PICTURE"===e.tagName&&w(e).forEach(n)},G={IMG:function(t,n){T(t,(function(t){N(t),M(t,n)})),N(t),M(t,n)},IFRAME:function(t,n){C(t,"src",s(t,n.data_src))},VIDEO:function(t,n){w(t).forEach((function(t){C(t,"src",s(t,n.data_src))})),C(t,"poster",s(t,n.data_poster)),C(t,"src",s(t,n.data_src)),t.load()}},S=function(t,n,e){var i=G[t.tagName];i&&(i(t,n),A(e),y(t,n.class_loading),f(t,"loading"),E(n.callback_loading,t,e),E(n.callback_reveal,t,e))},D=["IMG","IFRAME","VIDEO"],F=function(t){t&&(t.loadingCount-=1)},P=function(t,n){!n||n.toLoadCount||n.loadingCount||E(t.callback_finish,n)},V=function(t,n,e){t.addEventListener(n,e),t.llEvLisnrs[n]=e},j=function(t,n,e){t.removeEventListener(n,e)},U=function(t){return!!t.llEvLisnrs},$=function(t){if(U(t)){var n=t.llEvLisnrs;for(var e in n){var i=n[e];j(t,e,i)}delete t.llEvLisnrs}},q=function(t,n,e){!function(t){delete t.llTempImage}(t),F(e),L(t,n.class_loading),k(t,n,e)},H=function(t,n,e){var i=I(t)||t;if(!U(i)){!function(t,n,e){U(t)||(t.llEvLisnrs={}),V(t,"load",n),V(t,"error",e),"VIDEO"===t.tagName&&V(t,"loadeddata",n)}(i,(function(a){!function(t,n,e,i){q(n,e,i),y(n,e.class_loaded),f(n,"loaded"),E(e.callback_loaded,n,i),P(e,i)}(0,t,n,e),$(i)}),(function(a){!function(t,n,e,i){q(n,e,i),y(n,e.class_error),f(n,"error"),E(e.callback_error,n,i),P(e,i)}(0,t,n,e),$(i)}))}},B=function(t){t&&(t.toLoadCount-=1)},J=function(t,n,e){!function(t){t.llTempImage=document.createElement("img")}(t),H(t,n,e),function(t,n,e){var i=s(t,n.data_bg),a=s(t,n.data_bg_hidpi),r=o&&a?a:i;r&&(t.style.backgroundImage='url("'.concat(r,'")'),I(t).setAttribute("src",r),A(e),y(t,n.class_loading),f(t,"loading"),E(n.callback_loading,t,e),E(n.callback_reveal,t,e))}(t,n,e),function(t,n,e){var i=s(t,n.data_bg_multi),a=s(t,n.data_bg_multi_hidpi),r=o&&a?a:i;r&&(t.style.backgroundImage=r,y(t,n.class_applied),f(t,"applied"),k(t,n,e),E(n.callback_applied,t,e))}(t,n,e)},K=function(t,n,e){!function(t){return D.indexOf(t.tagName)>-1}(t)?J(t,n,e):function(t,n,e){H(t,n,e),S(t,n,e)}(t,n,e),B(e),P(n,e)},Q=function(t){var n=m(t);n&&(v(t)&&_(t),clearTimeout(n),h(t,null))},W=function(t,n,e,i){"IMG"===t.tagName&&($(t),function(t){T(t,(function(t){R(t)})),R(t)}(t),function(t){T(t,(function(t){x(t)})),x(t)}(t),L(t,e.class_loading),F(i),E(e.callback_cancel,t,n,i),setTimeout((function(){i.resetElementStatus(t,i)}),0))},X=function(t,n,e,i){E(e.callback_enter,t,n,i),p(t)||(e.load_delay?function(t,n,e){var i=n.load_delay,a=m(t);a||(a=setTimeout((function(){K(t,n,e),Q(t)}),i),f(t,"delayed"),h(t,a))}(t,e,i):K(t,e,i))},Y=function(t,n,e,i){g(t)||(e.cancel_on_exit&&function(t){return"loading"===d(t)}(t)&&W(t,n,e,i),E(e.callback_exit,t,n,i),e.load_delay&&v(t)&&Q(t))},Z=["IMG","IFRAME"],tt=function(t){return t.use_native&&"loading"in HTMLImageElement.prototype},nt=function(t,n,e){t.forEach((function(t){-1!==Z.indexOf(t.tagName)&&(t.setAttribute("loading","lazy"),function(t,n,e){H(t,n,e),S(t,n,e),B(e),f(t,"native"),P(n,e)}(t,n,e))})),e.toLoadCount=0},et=function(t){var n=t._settings;i&&!tt(t._settings)&&(t._observer=new IntersectionObserver((function(e){!function(t,n,e){t.forEach((function(t){return function(t){return t.isIntersecting||t.intersectionRatio>0}(t)?X(t.target,t,n,e):Y(t.target,t,n,e)}))}(e,n,t)}),function(t){return{root:t.container===document?null:t.container,rootMargin:t.thresholds||t.threshold+"px"}}(n)))},it=function(t){return Array.prototype.slice.call(t)},at=function(t){return t.container.querySelectorAll(t.elements_selector)},ot=function(t){return function(t){return"error"===d(t)}(t)},rt=function(t,n){return function(t){return it(t).filter(g)}(t||at(n))},ct=function(t){var n,e=t._settings;(n=at(e),it(n).filter(ot)).forEach((function(t){L(t,e.class_error),_(t)})),t.update()},lt=function(t,e){var i;this._settings=c(t),this.loadingCount=0,et(this),i=this,n&&window.addEventListener("online",(function(t){ct(i)})),this.update(e)};return lt.prototype={update:function(t){var n,a,o=this._settings,r=rt(t,o);(this.toLoadCount=r.length,!e&&i)?tt(o)?nt(r,o,this):(n=this._observer,a=r,function(t){t.disconnect()}(n),function(t,n){n.forEach((function(n){t.observe(n)}))}(n,a)):this.loadAll(r)},destroy:function(){this._observer&&this._observer.disconnect(),delete this._observer,delete this._settings,delete this.loadingCount,delete this.toLoadCount},loadAll:function(t){var n=this,e=this._settings;rt(t,e).forEach((function(t){K(t,e,n)}))},resetElementStatus:function(t){!function(t,n){p(t)&&function(t){t&&(t.toLoadCount+=1)}(n),f(t,null)}(t,this)},load:function(t){K(t,this._settings,this)}},lt.load=function(t,n){var e=c(n);K(t,e)},n&&function(t,n){if(n)if(n.length)for(var e,i=0;e=n[i];i+=1)l(t,e);else l(t,n)}(lt,window.lazyLoadOptions),lt})); | ||
define((function(){"use strict";function n(){return(n=Object.assign||function(n){for(var t=1;t<arguments.length;t++){var e=arguments[t];for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(n[i]=e[i])}return n}).apply(this,arguments)}var t="undefined"!=typeof window,e=t&&!("onscroll"in window)||"undefined"!=typeof navigator&&/(gle|ing|ro)bot|crawl|spider/i.test(navigator.userAgent),i=t&&"IntersectionObserver"in window,o=t&&"classList"in document.createElement("p"),r=t&&window.devicePixelRatio>1,a={elements_selector:"img",container:e||t?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_poster:"poster",class_applied:"applied",class_loading:"loading",class_loaded:"loaded",class_error:"error",unobserve_completed:!0,unobserve_entered:!1,cancel_on_exit:!1,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},c=function(t){return n({},a,t)},l=function(n,t){var e,i=new n(t);try{e=new CustomEvent("LazyLoad::Initialized",{detail:{instance:i}})}catch(n){(e=document.createEvent("CustomEvent")).initCustomEvent("LazyLoad::Initialized",!1,!1,{instance:i})}window.dispatchEvent(e)},s=function(n,t){return n.getAttribute("data-"+t)},u=function(n){return s(n,"ll-status")},d=function(n,t){return function(n,t,e){var i="data-"+t;null!==e?n.setAttribute(i,e):n.removeAttribute(i)}(n,"ll-status",t)},f=function(n){return d(n,null)},_=function(n){return null===u(n)},g=["loading","applied","loaded","error"],v=function(n,t,e,i){n&&(void 0===i?void 0===e?n(t):n(t,e):n(t,e,i))},b=function(n,t){o?n.classList.add(t):n.className+=(n.className?" ":"")+t},p=function(n,t){o?n.classList.remove(t):n.className=n.className.replace(new RegExp("(^|\\s+)"+t+"(\\s+|$)")," ").replace(/^\s+/,"").replace(/\s+$/,"")},h=function(n){return n.llTempImage},m=function(n,t){if(t){var e=t._observer;e&&e.unobserve(n)}},E=function(n,t){n&&(n.loadingCount+=t)},I=function(n,t){n&&(n.toLoadCount=t)},A=function(n){for(var t,e=[],i=0;t=n.children[i];i+=1)"SOURCE"===t.tagName&&e.push(t);return e},L=function(n,t,e){e&&n.setAttribute(t,e)},w=function(n,t){n.removeAttribute(t)},k=function(n){return!!n.llOriginalAttrs},y=function(n){if(!k(n)){var t={};t.src=n.getAttribute("src"),t.srcset=n.getAttribute("srcset"),t.sizes=n.getAttribute("sizes"),n.llOriginalAttrs=t}},O=function(n){if(k(n)){var t=n.llOriginalAttrs;L(n,"src",t.src),L(n,"srcset",t.srcset),L(n,"sizes",t.sizes)}},z=function(n,t){L(n,"sizes",s(n,t.data_sizes)),L(n,"srcset",s(n,t.data_srcset)),L(n,"src",s(n,t.data_src))},C=function(n){w(n,"src"),w(n,"srcset"),w(n,"sizes")},N=function(n,t){var e=n.parentNode;e&&"PICTURE"===e.tagName&&A(e).forEach(t)},x={IMG:function(n,t){N(n,(function(n){y(n),z(n,t)})),y(n),z(n,t)},IFRAME:function(n,t){L(n,"src",s(n,t.data_src))},VIDEO:function(n,t){A(n).forEach((function(n){L(n,"src",s(n,t.data_src))})),L(n,"poster",s(n,t.data_poster)),L(n,"src",s(n,t.data_src)),n.load()}},M=function(n,t,e){var i=x[n.tagName];i&&(i(n,t),E(e,1),b(n,t.class_loading),d(n,"loading"),v(t.callback_loading,n,e))},R=["IMG","IFRAME","VIDEO"],T=function(n,t){!t||function(n){return n.loadingCount>0}(t)||function(n){return n.toLoadCount>0}(t)||v(n.callback_finish,t)},G=function(n,t,e){n.addEventListener(t,e),n.llEvLisnrs[t]=e},D=function(n,t,e){n.removeEventListener(t,e)},F=function(n){return!!n.llEvLisnrs},P=function(n){if(F(n)){var t=n.llEvLisnrs;for(var e in t){var i=t[e];D(n,e,i)}delete n.llEvLisnrs}},S=function(n,t,e){!function(n){delete n.llTempImage}(n),E(e,-1),function(n){n&&(n.toLoadCount-=1)}(e),p(n,t.class_loading),t.unobserve_completed&&m(n,e)},V=function(n,t,e){var i=h(n)||n;if(!F(i)){!function(n,t,e){F(n)||(n.llEvLisnrs={}),G(n,"load",t),G(n,"error",e),"VIDEO"===n.tagName&&G(n,"loadeddata",t)}(i,(function(o){!function(n,t,e,i){S(t,e,i),b(t,e.class_loaded),d(t,"loaded"),v(e.callback_loaded,t,i),T(e,i)}(0,n,t,e),P(i)}),(function(o){!function(n,t,e,i){S(t,e,i),b(t,e.class_error),d(t,"error"),v(e.callback_error,t,i),T(e,i)}(0,n,t,e),P(i)}))}},j=function(n,t,e){!function(n){n.llTempImage=document.createElement("img")}(n),V(n,t,e),function(n,t,e){var i=s(n,t.data_bg),o=s(n,t.data_bg_hidpi),a=r&&o?o:i;a&&(n.style.backgroundImage='url("'.concat(a,'")'),h(n).setAttribute("src",a),E(e,1),b(n,t.class_loading),d(n,"loading"),v(t.callback_loading,n,e))}(n,t,e),function(n,t,e){var i=s(n,t.data_bg_multi),o=s(n,t.data_bg_multi_hidpi),a=r&&o?o:i;a&&(n.style.backgroundImage=a,b(n,t.class_applied),d(n,"applied"),v(t.callback_applied,n,e),t.unobserve_completed&&m(n,t))}(n,t,e)},U=function(n,t,e){!function(n){return R.indexOf(n.tagName)>-1}(n)?j(n,t,e):function(n,t,e){V(n,t,e),M(n,t,e)}(n,t,e),T(t,e)},$=function(n,t,e,i){"IMG"===n.tagName&&(P(n),function(n){N(n,(function(n){C(n)})),C(n)}(n),function(n){N(n,(function(n){O(n)})),O(n)}(n),p(n,e.class_loading),E(i,-1),v(e.callback_cancel,n,t,i),setTimeout((function(){f(n)}),0))},q=function(n,t,e,i){v(e.callback_enter,n,t,i),function(n){return g.indexOf(u(n))>-1}(n)||(e.unobserve_entered&&m(n,i),U(n,e,i))},H=function(n,t,e,i){_(n)||(e.cancel_on_exit&&function(n){return"loading"===u(n)}(n)&&$(n,t,e,i),v(e.callback_exit,n,t,i))},B=["IMG","IFRAME"],J=function(n){return n.use_native&&"loading"in HTMLImageElement.prototype},K=function(n,t,e){n.forEach((function(n){-1!==B.indexOf(n.tagName)&&(n.setAttribute("loading","lazy"),function(n,t,e){V(n,t,e),M(n,t,e),d(n,"native"),T(t,e)}(n,t,e))})),I(e,0)},Q=function(n,t){i&&!J(n)&&(t._observer=new IntersectionObserver((function(e){!function(n,t,e){n.forEach((function(n){return function(n){return n.isIntersecting||n.intersectionRatio>0}(n)?q(n.target,n,t,e):H(n.target,n,t,e)}))}(e,n,t)}),function(n){return{root:n.container===document?null:n.container,rootMargin:n.thresholds||n.threshold+"px"}}(n)))},W=function(n){return Array.prototype.slice.call(n)},X=function(n){return n.container.querySelectorAll(n.elements_selector)},Y=function(n){return function(n){return"error"===u(n)}(n)},Z=function(n,t){return function(n){return W(n).filter(_)}(n||X(t))},nn=function(n,t){var e;(e=X(n),W(e).filter(Y)).forEach((function(t){p(t,n.class_error),f(t)})),t.update()},tn=function(n,e){var i=c(n);this._settings=i,this.loadingCount=0,Q(i,this),function(n,e){t&&window.addEventListener("online",(function(){nn(n,e)}))}(i,this),this.update(e)};return tn.prototype={update:function(n){var t,o,r=this._settings,a=Z(n,r);(I(this,a.length),!e&&i)?J(r)?K(a,r,this):(t=this._observer,o=a,function(n){n.disconnect()}(t),function(n,t){t.forEach((function(t){n.observe(t)}))}(t,o)):this.loadAll(a)},destroy:function(){this._observer&&this._observer.disconnect(),delete this._observer,delete this._settings,delete this.loadingCount,delete this.toLoadCount},loadAll:function(n){var t=this,e=this._settings;Z(n,e).forEach((function(n){U(n,e,t)}))}},tn.load=function(n,t){var e=c(t);U(n,e)},tn.resetStatus=function(n){f(n)},t&&function(n,t){if(t)if(t.length)for(var e,i=0;e=t[i];i+=1)l(n,e);else l(n,t)}(tn,window.lazyLoadOptions),tn})); |
@@ -30,4 +30,4 @@ const runningOnBrowser = typeof window !== "undefined"; | ||
class_error: "error", | ||
load_delay: 0, | ||
auto_unobserve: true, | ||
unobserve_completed: true, | ||
unobserve_entered: false, | ||
cancel_on_exit: false, | ||
@@ -82,3 +82,2 @@ callback_enter: null, | ||
const statusDelayed = "delayed"; | ||
const statusLoading = "loading"; | ||
@@ -92,3 +91,2 @@ const statusLoaded = "loaded"; | ||
const statusDataName = "ll-status"; | ||
const timeoutDataName = "ll-timeout"; | ||
@@ -115,3 +113,2 @@ const getData = (element, attribute) => { | ||
const hasStatusError = (element) => getStatus(element) === statusError; | ||
const hasStatusDelayed = (element) => getStatus(element) === statusDelayed; | ||
@@ -122,5 +119,2 @@ const statusesAfterLoading = [statusLoading, statusApplied, statusLoaded, statusError]; | ||
const setTimeoutData = (element, value) => setData(element, timeoutDataName, value); | ||
const getTimeoutData = (element) => getData(element, timeoutDataName); | ||
const safeCallback = (callback, arg1, arg2, arg3) => { | ||
@@ -171,6 +165,6 @@ if (!callback) { | ||
const unobserve = (element, settings, instance) => { | ||
const unobserve = (element, instance) => { | ||
if (!instance) return; | ||
const observer = instance._observer; | ||
if (!observer || !settings.auto_unobserve) return; | ||
if (!observer) return; | ||
observer.unobserve(element); | ||
@@ -183,2 +177,21 @@ }; | ||
const updateLoadingCount = (instance, delta) => { | ||
if (!instance) return; | ||
instance.loadingCount += delta; | ||
}; | ||
const decreaseToLoadCount = (instance) => { | ||
if (!instance) return; | ||
instance.toLoadCount -= 1; | ||
}; | ||
const setToLoadCount = (instance, value) => { | ||
if (!instance) return; | ||
instance.toLoadCount = value; | ||
}; | ||
const isSomethingLoading = (instance) => instance.loadingCount > 0; | ||
const haveElementsToLoad = (instance) => instance.toLoadCount > 0; | ||
const _src_ = "src"; | ||
@@ -190,7 +203,2 @@ const _srcset_ = "srcset"; | ||
const increaseLoadingCount = (instance) => { | ||
if (!instance) return; | ||
instance.loadingCount += 1; | ||
}; | ||
const getSourceTags = (parentTag) => { | ||
@@ -222,3 +230,5 @@ let sourceTags = []; | ||
const saveOriginalImageAttributes = (element) => { | ||
if (hasOriginalAttributes(element)) return; | ||
if (hasOriginalAttributes(element)) { | ||
return; | ||
} | ||
const originalAttributes = {}; | ||
@@ -232,3 +242,5 @@ originalAttributes[_src_] = element.getAttribute(_src_); | ||
const restoreOriginalImageAttributes = (element) => { | ||
if (!hasOriginalAttributes(element)) return; | ||
if (!hasOriginalAttributes(element)) { | ||
return; | ||
} | ||
const originalAttributes = element.llOriginalAttrs; | ||
@@ -254,4 +266,5 @@ setAttributeIfValue(element, _src_, originalAttributes[_src_]); | ||
const parent = element.parentNode; | ||
if (!parent || parent.tagName !== _PICTURE_) return; | ||
if (!parent || parent.tagName !== _PICTURE_) { | ||
return; | ||
} | ||
let sourceTags = getSourceTags(parent); | ||
@@ -312,7 +325,6 @@ sourceTags.forEach(fn); | ||
// Annotate and notify loading | ||
increaseLoadingCount(instance); | ||
updateLoadingCount(instance, +1); | ||
addClass(element, settings.class_loading); | ||
setStatus(element, statusLoading); | ||
safeCallback(settings.callback_loading, element, instance); | ||
safeCallback(settings.callback_reveal, element, instance); // <== DEPRECATED | ||
}; | ||
@@ -327,3 +339,5 @@ | ||
const bgDataValue = isHiDpi && bgHiDpiValue ? bgHiDpiValue : bg1xValue; | ||
if (!bgDataValue) return; | ||
if (!bgDataValue) { | ||
return; | ||
} | ||
element.style.backgroundImage = bgDataValue; | ||
@@ -333,4 +347,7 @@ // Annotate and notify applied | ||
setStatus(element, statusApplied); | ||
unobserve(element, settings, instance); // Unobserve here because we can't do it on load | ||
safeCallback(settings.callback_applied, element, instance); | ||
if (settings.unobserve_completed) { | ||
// Unobserve now because we can't do it on load | ||
unobserve(element, settings); | ||
} | ||
}; | ||
@@ -340,10 +357,11 @@ | ||
const setSourcesFunction = setSourcesFunctions[element.tagName]; | ||
if (!setSourcesFunction) return; | ||
if (!setSourcesFunction) { | ||
return; | ||
} | ||
setSourcesFunction(element, settings); | ||
// Annotate and notify loading | ||
increaseLoadingCount(instance); | ||
updateLoadingCount(instance, +1); | ||
addClass(element, settings.class_loading); | ||
setStatus(element, statusLoading); | ||
safeCallback(settings.callback_loading, element, instance); | ||
safeCallback(settings.callback_reveal, element, instance); // <== DEPRECATED | ||
}; | ||
@@ -358,10 +376,6 @@ | ||
const decreaseLoadingCount = (instance) => { | ||
if (!instance) return; | ||
instance.loadingCount -= 1; | ||
}; | ||
const checkFinish = (settings, instance) => { | ||
if (!instance || instance.toLoadCount || instance.loadingCount) return; | ||
safeCallback(settings.callback_finish, instance); | ||
if (instance && !isSomethingLoading(instance) && !haveElementsToLoad(instance)) { | ||
safeCallback(settings.callback_finish, instance); | ||
} | ||
}; | ||
@@ -386,8 +400,11 @@ | ||
addEventListener(element, errorEventName, errorHandler); | ||
if (element.tagName !== "VIDEO") return; | ||
addEventListener(element, mediaLoadEventName, loadHandler); | ||
if (element.tagName === "VIDEO") { | ||
addEventListener(element, mediaLoadEventName, loadHandler); | ||
} | ||
}; | ||
const removeEventListeners = (element) => { | ||
if (!hasEventListeners(element)) return; | ||
if (!hasEventListeners(element)) { | ||
return; | ||
} | ||
const eventListeners = element.llEvLisnrs; | ||
@@ -403,5 +420,8 @@ for (let eventName in eventListeners) { | ||
deleteTempImage(element); | ||
decreaseLoadingCount(instance); | ||
updateLoadingCount(instance, -1); | ||
decreaseToLoadCount(instance); | ||
removeClass(element, settings.class_loading); | ||
unobserve(element, settings, instance); | ||
if (settings.unobserve_completed) { | ||
unobserve(element, instance); | ||
} | ||
}; | ||
@@ -427,4 +447,6 @@ | ||
const elementToListenTo = getTempImage(element) || element; | ||
if (hasEventListeners(elementToListenTo)) return; // <- when retry loading, e.g. with cancel_on_exit | ||
if (hasEventListeners(elementToListenTo)) { | ||
// This happens when loading is retried twice | ||
return; | ||
} | ||
const _loadHandler = (event) => { | ||
@@ -438,16 +460,5 @@ loadHandler(event, element, settings, instance); | ||
}; | ||
addEventListeners(elementToListenTo, _loadHandler, _errorHandler); | ||
}; | ||
const decreaseToLoadCount = (instance) => { | ||
if (!instance) return; | ||
instance.toLoadCount -= 1; | ||
}; | ||
const increaseToLoadCount = (instance) => { | ||
if (!instance) return; | ||
instance.toLoadCount += 1; | ||
}; | ||
const loadBackground = (element, settings, instance) => { | ||
@@ -471,3 +482,2 @@ addTempImage(element); | ||
} | ||
decreaseToLoadCount(instance); | ||
checkFinish(settings, instance); | ||
@@ -479,3 +489,2 @@ }; | ||
setSources(element, settings, instance); | ||
decreaseToLoadCount(instance); | ||
setStatus(element, statusNative); | ||
@@ -485,55 +494,35 @@ checkFinish(settings, instance); | ||
const cancelDelayLoad = (element) => { | ||
var timeoutId = getTimeoutData(element); | ||
if (!timeoutId) { | ||
return; // do nothing if timeout doesn't exist | ||
} | ||
if (hasStatusDelayed(element)) { // iffing because status could also be "loading" | ||
resetStatus(element); | ||
} | ||
clearTimeout(timeoutId); | ||
setTimeoutData(element, null); | ||
}; | ||
const delayLoad = (element, settings, instance) => { | ||
const loadDelay = settings.load_delay; | ||
let timeoutId = getTimeoutData(element); | ||
if (timeoutId) { | ||
return; // do nothing if timeout already set | ||
} | ||
timeoutId = setTimeout(function () { | ||
load(element, settings, instance); | ||
cancelDelayLoad(element); | ||
}, loadDelay); | ||
setStatus(element, statusDelayed); | ||
setTimeoutData(element, timeoutId); | ||
}; | ||
const cancelIfLoading = (element, entry, settings, instance) => { | ||
if (element.tagName !== "IMG") return; | ||
removeEventListeners(element); | ||
resetSourcesImg(element); | ||
restoreOriginalAttributesImg(element); | ||
removeClass(element, settings.class_loading); | ||
decreaseLoadingCount(instance); | ||
safeCallback(settings.callback_cancel, element, entry, instance); | ||
// setTimeout is needed because the "callback_cancel" implementation | ||
// could be out of the main thread, e.g. `img.setAttribute("src", "")` | ||
setTimeout(() => { | ||
instance.resetElementStatus(element, instance); | ||
}, 0); | ||
if (element.tagName !== "IMG") { | ||
// Can't cancel loading on anything but images | ||
return; | ||
} | ||
removeEventListeners(element); | ||
resetSourcesImg(element); | ||
restoreOriginalAttributesImg(element); | ||
removeClass(element, settings.class_loading); | ||
updateLoadingCount(instance, -1); | ||
safeCallback(settings.callback_cancel, element, entry, instance); | ||
// setTimeout is needed because the "callback_cancel" implementation | ||
// could be out of the main thread, e.g. `img.setAttribute("src", "")` | ||
setTimeout(() => { | ||
resetStatus(element); | ||
}, 0); | ||
}; | ||
const onIntersecting = (element, entry, settings, instance) => { | ||
const onEnter = (element, entry, settings, instance) => { | ||
safeCallback(settings.callback_enter, element, entry, instance); | ||
if (hasStatusAfterLoading(element)) return; //Prevent loading it again, e.g. on !auto_unobserve | ||
if (settings.load_delay) { | ||
delayLoad(element, settings, instance); | ||
return; | ||
if (hasStatusAfterLoading(element)) { | ||
return; //Prevent loading it again | ||
} | ||
if (settings.unobserve_entered) { | ||
unobserve(element, instance); | ||
} | ||
load(element, settings, instance); | ||
}; | ||
const onNotIntersecting = (element, entry, settings, instance) => { | ||
if (hasEmptyStatus(element)) return; //Ignore the first pass at landing | ||
const onExit = (element, entry, settings, instance) => { | ||
if (hasEmptyStatus(element)) { | ||
return; //Ignore the first pass, at landing | ||
} | ||
if (settings.cancel_on_exit && hasStatusLoading(element)) { | ||
@@ -543,5 +532,2 @@ cancelIfLoading(element, entry, settings, instance); | ||
safeCallback(settings.callback_exit, element, entry, instance); | ||
if (settings.load_delay && hasStatusDelayed(element)) { | ||
cancelDelayLoad(element); | ||
} | ||
}; | ||
@@ -563,3 +549,3 @@ | ||
}); | ||
instance.toLoadCount = 0; | ||
setToLoadCount(instance, 0); | ||
}; | ||
@@ -577,4 +563,4 @@ | ||
isIntersecting(entry) | ||
? onIntersecting(entry.target, entry, settings, instance) | ||
: onNotIntersecting(entry.target, entry, settings, instance) | ||
? onEnter(entry.target, entry, settings, instance) | ||
: onExit(entry.target, entry, settings, instance) | ||
); | ||
@@ -594,5 +580,4 @@ }; | ||
const setObserver = (instance) => { | ||
const settings = instance._settings; | ||
if (!supportsIntersectionObserver || shouldUseNative(instance._settings)) { | ||
const setObserver = (settings, instance) => { | ||
if (!supportsIntersectionObserver || shouldUseNative(settings)) { | ||
return; | ||
@@ -618,4 +603,3 @@ } | ||
const retryLazyLoad = instance => { | ||
const settings = instance._settings; | ||
const retryLazyLoad = (settings, instance) => { | ||
const errorElements = filterErrorElements(queryElements(settings)); | ||
@@ -629,23 +613,17 @@ errorElements.forEach(element => { | ||
const setOnlineCheck = instance => { | ||
const setOnlineCheck = (settings, instance) => { | ||
if (!runningOnBrowser) { | ||
return; | ||
} | ||
window.addEventListener("online", event => { | ||
retryLazyLoad(instance); | ||
window.addEventListener("online", () => { | ||
retryLazyLoad(settings, instance); | ||
}); | ||
}; | ||
const resetElementStatus = (element, instance) => { | ||
if (hasStatusAfterLoading(element)) { | ||
increaseToLoadCount(instance); | ||
} | ||
setStatus(element, null); | ||
}; | ||
const LazyLoad = function (customSettings, elements) { | ||
this._settings = getExtendedSettings(customSettings); | ||
const settings = getExtendedSettings(customSettings); | ||
this._settings = settings; | ||
this.loadingCount = 0; | ||
setObserver(this); | ||
setOnlineCheck(this); | ||
setObserver(settings, this); | ||
setOnlineCheck(settings, this); | ||
this.update(elements); | ||
@@ -658,3 +636,3 @@ }; | ||
const elementsToLoad = getElementsToLoad(givenNodeset, settings); | ||
this.toLoadCount = elementsToLoad.length; | ||
setToLoadCount(this, elementsToLoad.length); | ||
@@ -690,11 +668,2 @@ if (isBot || !supportsIntersectionObserver) { | ||
}); | ||
}, | ||
resetElementStatus: function (element) { | ||
resetElementStatus(element, this); | ||
}, | ||
// DEPRECATED | ||
load: function (element) { | ||
load(element, this._settings, this); | ||
} | ||
@@ -708,2 +677,6 @@ }; | ||
LazyLoad.resetStatus = (element) => { | ||
resetStatus(element); | ||
}; | ||
// Automatic instances creation if required (useful for async script loading) | ||
@@ -710,0 +683,0 @@ if (runningOnBrowser) { |
@@ -1,1 +0,1 @@ | ||
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&&"IntersectionObserver"in window,l=e&&"classList"in document.createElement("p"),s=e&&window.devicePixelRatio>1,n={elements_selector:"img",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_poster:"poster",class_applied:"applied",class_loading:"loading",class_loaded:"loaded",class_error:"error",load_delay:0,auto_unobserve:!0,cancel_on_exit:!1,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},i=e=>Object.assign({},n,e),o=function(e,t){var a;let l=new e(t);try{a=new CustomEvent("LazyLoad::Initialized",{detail:{instance:l}})}catch(e){(a=document.createEvent("CustomEvent")).initCustomEvent("LazyLoad::Initialized",!1,!1,{instance:l})}window.dispatchEvent(a)},r=(e,t)=>e.getAttribute("data-"+t),c=(e,t,a)=>{var l="data-"+t;null!==a?e.setAttribute(l,a):e.removeAttribute(l)},d=e=>r(e,"ll-status"),u=(e,t)=>c(e,"ll-status",t),_=e=>u(e,null),g=e=>null===d(e),b=e=>"delayed"===d(e),m=["loading","applied","loaded","error"],h=e=>m.indexOf(d(e))>-1,p=(e,t)=>c(e,"ll-timeout",t),v=e=>r(e,"ll-timeout"),f=(e,t,a,l)=>{e&&(void 0===l?void 0===a?e(t):e(t,a):e(t,a,l))},E=(e,t)=>{l?e.classList.add(t):e.className+=(e.className?" ":"")+t},L=(e,t)=>{l?e.classList.remove(t):e.className=e.className.replace(new RegExp("(^|\\s+)"+t+"(\\s+|$)")," ").replace(/^\s+/,"").replace(/\s+$/,"")},I=e=>e.llTempImage,k=(e,t,a)=>{if(!a)return;const l=a._observer;l&&t.auto_unobserve&&l.unobserve(e)},y=e=>{e&&(e.loadingCount+=1)},A=e=>{let t=[];for(let a,l=0;a=e.children[l];l+=1)"SOURCE"===a.tagName&&t.push(a);return t},w=(e,t,a)=>{a&&e.setAttribute(t,a)},C=(e,t)=>{e.removeAttribute(t)},z=e=>!!e.llOriginalAttrs,O=e=>{if(z(e))return;const t={};t.src=e.getAttribute("src"),t.srcset=e.getAttribute("srcset"),t.sizes=e.getAttribute("sizes"),e.llOriginalAttrs=t},N=e=>{if(!z(e))return;const t=e.llOriginalAttrs;w(e,"src",t.src),w(e,"srcset",t.srcset),w(e,"sizes",t.sizes)},x=(e,t)=>{w(e,"sizes",r(e,t.data_sizes)),w(e,"srcset",r(e,t.data_srcset)),w(e,"src",r(e,t.data_src))},M=e=>{C(e,"src"),C(e,"srcset"),C(e,"sizes")},R=(e,t)=>{const a=e.parentNode;if(!a||"PICTURE"!==a.tagName)return;A(a).forEach(t)},T={IMG:(e,t)=>{R(e,e=>{O(e),x(e,t)}),O(e),x(e,t)},IFRAME:(e,t)=>{w(e,"src",r(e,t.data_src))},VIDEO:(e,t)=>{A(e).forEach(e=>{w(e,"src",r(e,t.data_src))}),w(e,"poster",r(e,t.data_poster)),w(e,"src",r(e,t.data_src)),e.load()}},G=(e,t,a)=>{const l=T[e.tagName];l&&(l(e,t),y(a),E(e,t.class_loading),u(e,"loading"),f(t.callback_loading,e,a),f(t.callback_reveal,e,a))},S=["IMG","IFRAME","VIDEO"],D=e=>{e&&(e.loadingCount-=1)},F=(e,t)=>{!t||t.toLoadCount||t.loadingCount||f(e.callback_finish,t)},V=(e,t,a)=>{e.addEventListener(t,a),e.llEvLisnrs[t]=a},$=(e,t,a)=>{e.removeEventListener(t,a)},P=e=>!!e.llEvLisnrs,U=e=>{if(!P(e))return;const t=e.llEvLisnrs;for(let a in t){const l=t[a];$(e,a,l)}delete e.llEvLisnrs},j=(e,t,a)=>{(e=>{delete e.llTempImage})(e),D(a),L(e,t.class_loading),k(e,t,a)},q=(e,t,a)=>{const l=I(e)||e;if(P(l))return;((e,t,a)=>{P(e)||(e.llEvLisnrs={}),V(e,"load",t),V(e,"error",a),"VIDEO"===e.tagName&&V(e,"loadeddata",t)})(l,s=>{((e,t,a,l)=>{j(t,a,l),E(t,a.class_loaded),u(t,"loaded"),f(a.callback_loaded,t,l),F(a,l)})(0,e,t,a),U(l)},s=>{((e,t,a,l)=>{j(t,a,l),E(t,a.class_error),u(t,"error"),f(a.callback_error,t,l),F(a,l)})(0,e,t,a),U(l)})},H=e=>{e&&(e.toLoadCount-=1)},B=(e,t,a)=>{(e=>{e.llTempImage=document.createElement("img")})(e),q(e,t,a),((e,t,a)=>{const l=r(e,t.data_bg),n=r(e,t.data_bg_hidpi),i=s&&n?n:l;i&&(e.style.backgroundImage=`url("${i}")`,I(e).setAttribute("src",i),y(a),E(e,t.class_loading),u(e,"loading"),f(t.callback_loading,e,a),f(t.callback_reveal,e,a))})(e,t,a),((e,t,a)=>{const l=r(e,t.data_bg_multi),n=r(e,t.data_bg_multi_hidpi),i=s&&n?n:l;i&&(e.style.backgroundImage=i,E(e,t.class_applied),u(e,"applied"),k(e,t,a),f(t.callback_applied,e,a))})(e,t,a)},J=(e,t,a)=>{(e=>S.indexOf(e.tagName)>-1)(e)?((e,t,a)=>{q(e,t,a),G(e,t,a)})(e,t,a):B(e,t,a),H(a),F(t,a)},K=e=>{var t=v(e);t&&(b(e)&&_(e),clearTimeout(t),p(e,null))},Q=(e,t,a,l)=>{"IMG"===e.tagName&&(U(e),(e=>{R(e,e=>{M(e)}),M(e)})(e),(e=>{R(e,e=>{N(e)}),N(e)})(e),L(e,a.class_loading),D(l),f(a.callback_cancel,e,t,l),setTimeout(()=>{l.resetElementStatus(e,l)},0))},W=(e,t,a,l)=>{f(a.callback_enter,e,t,l),h(e)||(a.load_delay?((e,t,a)=>{const l=t.load_delay;let s=v(e);s||(s=setTimeout((function(){J(e,t,a),K(e)}),l),u(e,"delayed"),p(e,s))})(e,a,l):J(e,a,l))},X=(e,t,a,l)=>{g(e)||(a.cancel_on_exit&&(e=>"loading"===d(e))(e)&&Q(e,t,a,l),f(a.callback_exit,e,t,l),a.load_delay&&b(e)&&K(e))},Y=["IMG","IFRAME"],Z=e=>e.use_native&&"loading"in HTMLImageElement.prototype,ee=(e,t,a)=>{e.forEach(e=>{-1!==Y.indexOf(e.tagName)&&(e.setAttribute("loading","lazy"),((e,t,a)=>{q(e,t,a),G(e,t,a),H(a),u(e,"native"),F(t,a)})(e,t,a))}),a.toLoadCount=0},te=e=>{const t=e._settings;a&&!Z(e._settings)&&(e._observer=new IntersectionObserver(a=>{((e,t,a)=>{e.forEach(e=>(e=>e.isIntersecting||e.intersectionRatio>0)(e)?W(e.target,e,t,a):X(e.target,e,t,a))})(a,t,e)},(e=>({root:e.container===document?null:e.container,rootMargin:e.thresholds||e.threshold+"px"}))(t)))},ae=e=>Array.prototype.slice.call(e),le=e=>e.container.querySelectorAll(e.elements_selector),se=e=>(e=>"error"===d(e))(e),ne=(e,t)=>(e=>ae(e).filter(g))(e||le(t)),ie=e=>{const t=e._settings;var a;(a=le(t),ae(a).filter(se)).forEach(e=>{L(e,t.class_error),_(e)}),e.update()},oe=function(t,a){var l;this._settings=i(t),this.loadingCount=0,te(this),l=this,e&&window.addEventListener("online",e=>{ie(l)}),this.update(a)};oe.prototype={update:function(e){const l=this._settings,s=ne(e,l);var n,i;(this.toLoadCount=s.length,!t&&a)?Z(l)?ee(s,l,this):(n=this._observer,i=s,(e=>{e.disconnect()})(n),((e,t)=>{t.forEach(t=>{e.observe(t)})})(n,i)):this.loadAll(s)},destroy:function(){this._observer&&this._observer.disconnect(),delete this._observer,delete this._settings,delete this.loadingCount,delete this.toLoadCount},loadAll:function(e){const t=this._settings;ne(e,t).forEach(e=>{J(e,t,this)})},resetElementStatus:function(e){((e,t)=>{h(e)&&(e=>{e&&(e.toLoadCount+=1)})(t),u(e,null)})(e,this)},load:function(e){J(e,this._settings,this)}},oe.load=(e,t)=>{const a=i(t);J(e,a)},e&&((e,t)=>{if(t)if(t.length)for(let a,l=0;a=t[l];l+=1)o(e,a);else o(e,t)})(oe,window.lazyLoadOptions);export default oe; | ||
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&&"IntersectionObserver"in window,s=e&&"classList"in document.createElement("p"),l=e&&window.devicePixelRatio>1,n={elements_selector:"img",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_poster:"poster",class_applied:"applied",class_loading:"loading",class_loaded:"loaded",class_error:"error",unobserve_completed:!0,unobserve_entered:!1,cancel_on_exit:!1,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},r=e=>Object.assign({},n,e),i=function(e,t){var a;let s=new e(t);try{a=new CustomEvent("LazyLoad::Initialized",{detail:{instance:s}})}catch(e){(a=document.createEvent("CustomEvent")).initCustomEvent("LazyLoad::Initialized",!1,!1,{instance:s})}window.dispatchEvent(a)},o=(e,t)=>e.getAttribute("data-"+t),c=e=>o(e,"ll-status"),d=(e,t)=>((e,t,a)=>{var s="data-"+t;null!==a?e.setAttribute(s,a):e.removeAttribute(s)})(e,"ll-status",t),u=e=>d(e,null),_=e=>null===c(e),g=["loading","applied","loaded","error"],b=(e,t,a,s)=>{e&&(void 0===s?void 0===a?e(t):e(t,a):e(t,a,s))},p=(e,t)=>{s?e.classList.add(t):e.className+=(e.className?" ":"")+t},m=(e,t)=>{s?e.classList.remove(t):e.className=e.className.replace(new RegExp("(^|\\s+)"+t+"(\\s+|$)")," ").replace(/^\s+/,"").replace(/\s+$/,"")},h=e=>e.llTempImage,v=(e,t)=>{if(!t)return;const a=t._observer;a&&a.unobserve(e)},f=(e,t)=>{e&&(e.loadingCount+=t)},E=(e,t)=>{e&&(e.toLoadCount=t)},I=e=>{let t=[];for(let a,s=0;a=e.children[s];s+=1)"SOURCE"===a.tagName&&t.push(a);return t},A=(e,t,a)=>{a&&e.setAttribute(t,a)},L=(e,t)=>{e.removeAttribute(t)},k=e=>!!e.llOriginalAttrs,w=e=>{if(k(e))return;const t={};t.src=e.getAttribute("src"),t.srcset=e.getAttribute("srcset"),t.sizes=e.getAttribute("sizes"),e.llOriginalAttrs=t},y=e=>{if(!k(e))return;const t=e.llOriginalAttrs;A(e,"src",t.src),A(e,"srcset",t.srcset),A(e,"sizes",t.sizes)},z=(e,t)=>{A(e,"sizes",o(e,t.data_sizes)),A(e,"srcset",o(e,t.data_srcset)),A(e,"src",o(e,t.data_src))},O=e=>{L(e,"src"),L(e,"srcset"),L(e,"sizes")},C=(e,t)=>{const a=e.parentNode;if(!a||"PICTURE"!==a.tagName)return;I(a).forEach(t)},N={IMG:(e,t)=>{C(e,e=>{w(e),z(e,t)}),w(e),z(e,t)},IFRAME:(e,t)=>{A(e,"src",o(e,t.data_src))},VIDEO:(e,t)=>{I(e).forEach(e=>{A(e,"src",o(e,t.data_src))}),A(e,"poster",o(e,t.data_poster)),A(e,"src",o(e,t.data_src)),e.load()}},x=(e,t,a)=>{const s=N[e.tagName];s&&(s(e,t),f(a,1),p(e,t.class_loading),d(e,"loading"),b(t.callback_loading,e,a))},M=["IMG","IFRAME","VIDEO"],R=(e,t)=>{!t||(e=>e.loadingCount>0)(t)||(e=>e.toLoadCount>0)(t)||b(e.callback_finish,t)},T=(e,t,a)=>{e.addEventListener(t,a),e.llEvLisnrs[t]=a},G=(e,t,a)=>{e.removeEventListener(t,a)},D=e=>!!e.llEvLisnrs,F=e=>{if(!D(e))return;const t=e.llEvLisnrs;for(let a in t){const s=t[a];G(e,a,s)}delete e.llEvLisnrs},S=(e,t,a)=>{(e=>{delete e.llTempImage})(e),f(a,-1),(e=>{e&&(e.toLoadCount-=1)})(a),m(e,t.class_loading),t.unobserve_completed&&v(e,a)},V=(e,t,a)=>{const s=h(e)||e;if(D(s))return;((e,t,a)=>{D(e)||(e.llEvLisnrs={}),T(e,"load",t),T(e,"error",a),"VIDEO"===e.tagName&&T(e,"loadeddata",t)})(s,l=>{((e,t,a,s)=>{S(t,a,s),p(t,a.class_loaded),d(t,"loaded"),b(a.callback_loaded,t,s),R(a,s)})(0,e,t,a),F(s)},l=>{((e,t,a,s)=>{S(t,a,s),p(t,a.class_error),d(t,"error"),b(a.callback_error,t,s),R(a,s)})(0,e,t,a),F(s)})},$=(e,t,a)=>{(e=>{e.llTempImage=document.createElement("img")})(e),V(e,t,a),((e,t,a)=>{const s=o(e,t.data_bg),n=o(e,t.data_bg_hidpi),r=l&&n?n:s;r&&(e.style.backgroundImage=`url("${r}")`,h(e).setAttribute("src",r),f(a,1),p(e,t.class_loading),d(e,"loading"),b(t.callback_loading,e,a))})(e,t,a),((e,t,a)=>{const s=o(e,t.data_bg_multi),n=o(e,t.data_bg_multi_hidpi),r=l&&n?n:s;r&&(e.style.backgroundImage=r,p(e,t.class_applied),d(e,"applied"),b(t.callback_applied,e,a),t.unobserve_completed&&v(e,t))})(e,t,a)},P=(e,t,a)=>{(e=>M.indexOf(e.tagName)>-1)(e)?((e,t,a)=>{V(e,t,a),x(e,t,a)})(e,t,a):$(e,t,a),R(t,a)},U=(e,t,a,s)=>{"IMG"===e.tagName&&(F(e),(e=>{C(e,e=>{O(e)}),O(e)})(e),(e=>{C(e,e=>{y(e)}),y(e)})(e),m(e,a.class_loading),f(s,-1),b(a.callback_cancel,e,t,s),setTimeout(()=>{u(e)},0))},j=(e,t,a,s)=>{b(a.callback_enter,e,t,s),(e=>g.indexOf(c(e))>-1)(e)||(a.unobserve_entered&&v(e,s),P(e,a,s))},q=(e,t,a,s)=>{_(e)||(a.cancel_on_exit&&(e=>"loading"===c(e))(e)&&U(e,t,a,s),b(a.callback_exit,e,t,s))},H=["IMG","IFRAME"],B=e=>e.use_native&&"loading"in HTMLImageElement.prototype,J=(e,t,a)=>{e.forEach(e=>{-1!==H.indexOf(e.tagName)&&(e.setAttribute("loading","lazy"),((e,t,a)=>{V(e,t,a),x(e,t,a),d(e,"native"),R(t,a)})(e,t,a))}),E(a,0)},K=(e,t)=>{a&&!B(e)&&(t._observer=new IntersectionObserver(a=>{((e,t,a)=>{e.forEach(e=>(e=>e.isIntersecting||e.intersectionRatio>0)(e)?j(e.target,e,t,a):q(e.target,e,t,a))})(a,e,t)},(e=>({root:e.container===document?null:e.container,rootMargin:e.thresholds||e.threshold+"px"}))(e)))},Q=e=>Array.prototype.slice.call(e),W=e=>e.container.querySelectorAll(e.elements_selector),X=e=>(e=>"error"===c(e))(e),Y=(e,t)=>(e=>Q(e).filter(_))(e||W(t)),Z=(e,t)=>{var a;(a=W(e),Q(a).filter(X)).forEach(t=>{m(t,e.class_error),u(t)}),t.update()},ee=function(t,a){const s=r(t);this._settings=s,this.loadingCount=0,K(s,this),((t,a)=>{e&&window.addEventListener("online",()=>{Z(t,a)})})(s,this),this.update(a)};ee.prototype={update:function(e){const s=this._settings,l=Y(e,s);var n,r;(E(this,l.length),!t&&a)?B(s)?J(l,s,this):(n=this._observer,r=l,(e=>{e.disconnect()})(n),((e,t)=>{t.forEach(t=>{e.observe(t)})})(n,r)):this.loadAll(l)},destroy:function(){this._observer&&this._observer.disconnect(),delete this._observer,delete this._settings,delete this.loadingCount,delete this.toLoadCount},loadAll:function(e){const t=this._settings;Y(e,t).forEach(e=>{P(e,t,this)})}},ee.load=(e,t)=>{const a=r(t);P(e,a)},ee.resetStatus=e=>{u(e)},e&&((e,t)=>{if(t)if(t.length)for(let a,s=0;a=t[s];s+=1)i(e,a);else i(e,t)})(ee,window.lazyLoadOptions);export default ee; |
@@ -45,4 +45,4 @@ var LazyLoad = (function () { | ||
class_error: "error", | ||
load_delay: 0, | ||
auto_unobserve: true, | ||
unobserve_completed: true, | ||
unobserve_entered: false, | ||
cancel_on_exit: false, | ||
@@ -106,3 +106,2 @@ callback_enter: null, | ||
var statusDelayed = "delayed"; | ||
var statusLoading = "loading"; | ||
@@ -116,3 +115,2 @@ var statusLoaded = "loaded"; | ||
var statusDataName = "ll-status"; | ||
var timeoutDataName = "ll-timeout"; | ||
var getData = function getData(element, attribute) { | ||
@@ -149,5 +147,2 @@ return element.getAttribute(dataPrefix + attribute); | ||
}; | ||
var hasStatusDelayed = function hasStatusDelayed(element) { | ||
return getStatus(element) === statusDelayed; | ||
}; | ||
var statusesAfterLoading = [statusLoading, statusApplied, statusLoaded, statusError]; | ||
@@ -157,8 +152,2 @@ var hasStatusAfterLoading = function hasStatusAfterLoading(element) { | ||
}; | ||
var setTimeoutData = function setTimeoutData(element, value) { | ||
return setData(element, timeoutDataName, value); | ||
}; | ||
var getTimeoutData = function getTimeoutData(element) { | ||
return getData(element, timeoutDataName); | ||
}; | ||
@@ -210,6 +199,6 @@ var safeCallback = function safeCallback(callback, arg1, arg2, arg3) { | ||
var unobserve = function unobserve(element, settings, instance) { | ||
var unobserve = function unobserve(element, instance) { | ||
if (!instance) return; | ||
var observer = instance._observer; | ||
if (!observer || !settings.auto_unobserve) return; | ||
if (!observer) return; | ||
observer.unobserve(element); | ||
@@ -221,2 +210,21 @@ }; | ||
var updateLoadingCount = function updateLoadingCount(instance, delta) { | ||
if (!instance) return; | ||
instance.loadingCount += delta; | ||
}; | ||
var decreaseToLoadCount = function decreaseToLoadCount(instance) { | ||
if (!instance) return; | ||
instance.toLoadCount -= 1; | ||
}; | ||
var setToLoadCount = function 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; | ||
}; | ||
var _src_ = "src"; | ||
@@ -227,6 +235,2 @@ var _srcset_ = "srcset"; | ||
var _PICTURE_ = "PICTURE"; | ||
var increaseLoadingCount = function increaseLoadingCount(instance) { | ||
if (!instance) return; | ||
instance.loadingCount += 1; | ||
}; | ||
var getSourceTags = function getSourceTags(parentTag) { | ||
@@ -257,3 +261,6 @@ var sourceTags = []; | ||
var saveOriginalImageAttributes = function saveOriginalImageAttributes(element) { | ||
if (hasOriginalAttributes(element)) return; | ||
if (hasOriginalAttributes(element)) { | ||
return; | ||
} | ||
var originalAttributes = {}; | ||
@@ -266,3 +273,6 @@ originalAttributes[_src_] = element.getAttribute(_src_); | ||
var restoreOriginalImageAttributes = function restoreOriginalImageAttributes(element) { | ||
if (!hasOriginalAttributes(element)) return; | ||
if (!hasOriginalAttributes(element)) { | ||
return; | ||
} | ||
var originalAttributes = element.llOriginalAttrs; | ||
@@ -285,3 +295,7 @@ setAttributeIfValue(element, _src_, originalAttributes[_src_]); | ||
var parent = element.parentNode; | ||
if (!parent || parent.tagName !== _PICTURE_) return; | ||
if (!parent || parent.tagName !== _PICTURE_) { | ||
return; | ||
} | ||
var sourceTags = getSourceTags(parent); | ||
@@ -335,7 +349,6 @@ sourceTags.forEach(fn); | ||
increaseLoadingCount(instance); | ||
updateLoadingCount(instance, +1); | ||
addClass(element, settings.class_loading); | ||
setStatus(element, statusLoading); | ||
safeCallback(settings.callback_loading, element, instance); | ||
safeCallback(settings.callback_reveal, element, instance); // <== DEPRECATED | ||
}; // NOTE: THE TEMP IMAGE TRICK CANNOT BE DONE WITH data-multi-bg | ||
@@ -349,3 +362,7 @@ // BECAUSE INSIDE ITS VALUES MUST BE WRAPPED WITH URL() AND ONE OF THEM | ||
var bgDataValue = isHiDpi && bgHiDpiValue ? bgHiDpiValue : bg1xValue; | ||
if (!bgDataValue) return; | ||
if (!bgDataValue) { | ||
return; | ||
} | ||
element.style.backgroundImage = bgDataValue; // Annotate and notify applied | ||
@@ -355,16 +372,22 @@ | ||
setStatus(element, statusApplied); | ||
unobserve(element, settings, instance); // Unobserve here because we can't do it on load | ||
safeCallback(settings.callback_applied, element, instance); | ||
safeCallback(settings.callback_applied, element, instance); | ||
if (settings.unobserve_completed) { | ||
// Unobserve now because we can't do it on load | ||
unobserve(element, settings); | ||
} | ||
}; | ||
var setSources = function setSources(element, settings, instance) { | ||
var setSourcesFunction = setSourcesFunctions[element.tagName]; | ||
if (!setSourcesFunction) return; | ||
if (!setSourcesFunction) { | ||
return; | ||
} | ||
setSourcesFunction(element, settings); // Annotate and notify loading | ||
increaseLoadingCount(instance); | ||
updateLoadingCount(instance, +1); | ||
addClass(element, settings.class_loading); | ||
setStatus(element, statusLoading); | ||
safeCallback(settings.callback_loading, element, instance); | ||
safeCallback(settings.callback_reveal, element, instance); // <== DEPRECATED | ||
}; | ||
@@ -379,9 +402,6 @@ | ||
}; | ||
var decreaseLoadingCount = function decreaseLoadingCount(instance) { | ||
if (!instance) return; | ||
instance.loadingCount -= 1; | ||
}; | ||
var checkFinish = function checkFinish(settings, instance) { | ||
if (!instance || instance.toLoadCount || instance.loadingCount) return; | ||
safeCallback(settings.callback_finish, instance); | ||
if (instance && !isSomethingLoading(instance) && !haveElementsToLoad(instance)) { | ||
safeCallback(settings.callback_finish, instance); | ||
} | ||
}; | ||
@@ -402,7 +422,12 @@ var addEventListener = function addEventListener(element, eventName, handler) { | ||
addEventListener(element, errorEventName, errorHandler); | ||
if (element.tagName !== "VIDEO") return; | ||
addEventListener(element, mediaLoadEventName, loadHandler); | ||
if (element.tagName === "VIDEO") { | ||
addEventListener(element, mediaLoadEventName, loadHandler); | ||
} | ||
}; | ||
var removeEventListeners = function removeEventListeners(element) { | ||
if (!hasEventListeners(element)) return; | ||
if (!hasEventListeners(element)) { | ||
return; | ||
} | ||
var eventListeners = element.llEvLisnrs; | ||
@@ -419,5 +444,9 @@ | ||
deleteTempImage(element); | ||
decreaseLoadingCount(instance); | ||
updateLoadingCount(instance, -1); | ||
decreaseToLoadCount(instance); | ||
removeClass(element, settings.class_loading); | ||
unobserve(element, settings, instance); | ||
if (settings.unobserve_completed) { | ||
unobserve(element, instance); | ||
} | ||
}; | ||
@@ -440,4 +469,8 @@ var loadHandler = function loadHandler(event, element, settings, instance) { | ||
var elementToListenTo = getTempImage(element) || element; | ||
if (hasEventListeners(elementToListenTo)) return; // <- when retry loading, e.g. with cancel_on_exit | ||
if (hasEventListeners(elementToListenTo)) { | ||
// This happens when loading is retried twice | ||
return; | ||
} | ||
var _loadHandler = function _loadHandler(event) { | ||
@@ -456,11 +489,2 @@ loadHandler(event, element, settings, instance); | ||
var decreaseToLoadCount = function decreaseToLoadCount(instance) { | ||
if (!instance) return; | ||
instance.toLoadCount -= 1; | ||
}; | ||
var increaseToLoadCount = function increaseToLoadCount(instance) { | ||
if (!instance) return; | ||
instance.toLoadCount += 1; | ||
}; | ||
var loadBackground = function loadBackground(element, settings, instance) { | ||
@@ -485,3 +509,2 @@ addTempImage(element); | ||
decreaseToLoadCount(instance); | ||
checkFinish(settings, instance); | ||
@@ -492,3 +515,2 @@ }; | ||
setSources(element, settings, instance); | ||
decreaseToLoadCount(instance); | ||
setStatus(element, statusNative); | ||
@@ -498,35 +520,8 @@ checkFinish(settings, instance); | ||
var cancelDelayLoad = function cancelDelayLoad(element) { | ||
var timeoutId = getTimeoutData(element); | ||
if (!timeoutId) { | ||
return; // do nothing if timeout doesn't exist | ||
var cancelIfLoading = function cancelIfLoading(element, entry, settings, instance) { | ||
if (element.tagName !== "IMG") { | ||
// Can't cancel loading on anything but images | ||
return; | ||
} | ||
if (hasStatusDelayed(element)) { | ||
// iffing because status could also be "loading" | ||
resetStatus(element); | ||
} | ||
clearTimeout(timeoutId); | ||
setTimeoutData(element, null); | ||
}; | ||
var delayLoad = function delayLoad(element, settings, instance) { | ||
var loadDelay = settings.load_delay; | ||
var timeoutId = getTimeoutData(element); | ||
if (timeoutId) { | ||
return; // do nothing if timeout already set | ||
} | ||
timeoutId = setTimeout(function () { | ||
load(element, settings, instance); | ||
cancelDelayLoad(element); | ||
}, loadDelay); | ||
setStatus(element, statusDelayed); | ||
setTimeoutData(element, timeoutId); | ||
}; | ||
var cancelIfLoading = function cancelIfLoading(element, entry, settings, instance) { | ||
if (element.tagName !== "IMG") return; | ||
removeEventListeners(element); | ||
@@ -536,3 +531,3 @@ resetSourcesImg(element); | ||
removeClass(element, settings.class_loading); | ||
decreaseLoadingCount(instance); | ||
updateLoadingCount(instance, -1); | ||
safeCallback(settings.callback_cancel, element, entry, instance); // setTimeout is needed because the "callback_cancel" implementation | ||
@@ -542,19 +537,23 @@ // could be out of the main thread, e.g. `img.setAttribute("src", "")` | ||
setTimeout(function () { | ||
instance.resetElementStatus(element, instance); | ||
resetStatus(element); | ||
}, 0); | ||
}; | ||
var onIntersecting = function onIntersecting(element, entry, settings, instance) { | ||
var onEnter = function onEnter(element, entry, settings, instance) { | ||
safeCallback(settings.callback_enter, element, entry, instance); | ||
if (hasStatusAfterLoading(element)) return; //Prevent loading it again, e.g. on !auto_unobserve | ||
if (settings.load_delay) { | ||
delayLoad(element, settings, instance); | ||
return; | ||
if (hasStatusAfterLoading(element)) { | ||
return; //Prevent loading it again | ||
} | ||
if (settings.unobserve_entered) { | ||
unobserve(element, instance); | ||
} | ||
load(element, settings, instance); | ||
}; | ||
var onNotIntersecting = function onNotIntersecting(element, entry, settings, instance) { | ||
if (hasEmptyStatus(element)) return; //Ignore the first pass at landing | ||
var onExit = function onExit(element, entry, settings, instance) { | ||
if (hasEmptyStatus(element)) { | ||
return; //Ignore the first pass, at landing | ||
} | ||
@@ -566,6 +565,2 @@ if (settings.cancel_on_exit && hasStatusLoading(element)) { | ||
safeCallback(settings.callback_exit, element, entry, instance); | ||
if (settings.load_delay && hasStatusDelayed(element)) { | ||
cancelDelayLoad(element); | ||
} | ||
}; | ||
@@ -588,3 +583,3 @@ | ||
}); | ||
instance.toLoadCount = 0; | ||
setToLoadCount(instance, 0); | ||
}; | ||
@@ -605,3 +600,3 @@ | ||
entries.forEach(function (entry) { | ||
return isIntersecting(entry) ? onIntersecting(entry.target, entry, settings, instance) : onNotIntersecting(entry.target, entry, settings, instance); | ||
return isIntersecting(entry) ? onEnter(entry.target, entry, settings, instance) : onExit(entry.target, entry, settings, instance); | ||
}); | ||
@@ -619,6 +614,4 @@ }; | ||
}; | ||
var setObserver = function setObserver(instance) { | ||
var settings = instance._settings; | ||
if (!supportsIntersectionObserver || shouldUseNative(instance._settings)) { | ||
var setObserver = function setObserver(settings, instance) { | ||
if (!supportsIntersectionObserver || shouldUseNative(settings)) { | ||
return; | ||
@@ -651,4 +644,3 @@ } | ||
var retryLazyLoad = function retryLazyLoad(instance) { | ||
var settings = instance._settings; | ||
var retryLazyLoad = function retryLazyLoad(settings, instance) { | ||
var errorElements = filterErrorElements(queryElements(settings)); | ||
@@ -661,3 +653,3 @@ errorElements.forEach(function (element) { | ||
}; | ||
var setOnlineCheck = function setOnlineCheck(instance) { | ||
var setOnlineCheck = function setOnlineCheck(settings, instance) { | ||
if (!runningOnBrowser) { | ||
@@ -667,20 +659,13 @@ return; | ||
window.addEventListener("online", function (event) { | ||
retryLazyLoad(instance); | ||
window.addEventListener("online", function () { | ||
retryLazyLoad(settings, instance); | ||
}); | ||
}; | ||
var resetElementStatus = function resetElementStatus(element, instance) { | ||
if (hasStatusAfterLoading(element)) { | ||
increaseToLoadCount(instance); | ||
} | ||
setStatus(element, null); | ||
}; | ||
var LazyLoad = function LazyLoad(customSettings, elements) { | ||
this._settings = getExtendedSettings(customSettings); | ||
var settings = getExtendedSettings(customSettings); | ||
this._settings = settings; | ||
this.loadingCount = 0; | ||
setObserver(this); | ||
setOnlineCheck(this); | ||
setObserver(settings, this); | ||
setOnlineCheck(settings, this); | ||
this.update(elements); | ||
@@ -693,3 +678,3 @@ }; | ||
var elementsToLoad = getElementsToLoad(givenNodeset, settings); | ||
this.toLoadCount = elementsToLoad.length; | ||
setToLoadCount(this, elementsToLoad.length); | ||
@@ -727,9 +712,2 @@ if (isBot || !supportsIntersectionObserver) { | ||
}); | ||
}, | ||
resetElementStatus: function resetElementStatus$1(element) { | ||
resetElementStatus(element, this); | ||
}, | ||
// DEPRECATED | ||
load: function load$1(element) { | ||
load(element, this._settings, this); | ||
} | ||
@@ -740,4 +718,7 @@ }; | ||
var settings = getExtendedSettings(customSettings); | ||
load(element, settings); | ||
}; | ||
load(element, settings); | ||
LazyLoad.resetStatus = function (element) { | ||
resetStatus(element); | ||
}; // Automatic instances creation if required (useful for async script loading) | ||
@@ -744,0 +725,0 @@ |
@@ -1,1 +0,1 @@ | ||
var LazyLoad=function(){"use strict";function t(){return(t=Object.assign||function(t){for(var n=1;n<arguments.length;n++){var e=arguments[n];for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])}return t}).apply(this,arguments)}var n="undefined"!=typeof window,e=n&&!("onscroll"in window)||"undefined"!=typeof navigator&&/(gle|ing|ro)bot|crawl|spider/i.test(navigator.userAgent),i=n&&"IntersectionObserver"in window,a=n&&"classList"in document.createElement("p"),o=n&&window.devicePixelRatio>1,r={elements_selector:"img",container:e||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_poster:"poster",class_applied:"applied",class_loading:"loading",class_loaded:"loaded",class_error:"error",load_delay:0,auto_unobserve:!0,cancel_on_exit:!1,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},c=function(n){return t({},r,n)},l=function(t,n){var e,i=new t(n);try{e=new CustomEvent("LazyLoad::Initialized",{detail:{instance:i}})}catch(t){(e=document.createEvent("CustomEvent")).initCustomEvent("LazyLoad::Initialized",!1,!1,{instance:i})}window.dispatchEvent(e)},s=function(t,n){return t.getAttribute("data-"+n)},u=function(t,n,e){var i="data-"+n;null!==e?t.setAttribute(i,e):t.removeAttribute(i)},d=function(t){return s(t,"ll-status")},f=function(t,n){return u(t,"ll-status",n)},_=function(t){return f(t,null)},g=function(t){return null===d(t)},v=function(t){return"delayed"===d(t)},b=["loading","applied","loaded","error"],p=function(t){return b.indexOf(d(t))>-1},h=function(t,n){return u(t,"ll-timeout",n)},m=function(t){return s(t,"ll-timeout")},E=function(t,n,e,i){t&&(void 0===i?void 0===e?t(n):t(n,e):t(n,e,i))},y=function(t,n){a?t.classList.add(n):t.className+=(t.className?" ":"")+n},L=function(t,n){a?t.classList.remove(n):t.className=t.className.replace(new RegExp("(^|\\s+)"+n+"(\\s+|$)")," ").replace(/^\s+/,"").replace(/\s+$/,"")},I=function(t){return t.llTempImage},k=function(t,n,e){if(e){var i=e._observer;i&&n.auto_unobserve&&i.unobserve(t)}},A=function(t){t&&(t.loadingCount+=1)},w=function(t){for(var n,e=[],i=0;n=t.children[i];i+=1)"SOURCE"===n.tagName&&e.push(n);return e},z=function(t,n,e){e&&t.setAttribute(n,e)},C=function(t,n){t.removeAttribute(n)},O=function(t){return!!t.llOriginalAttrs},N=function(t){if(!O(t)){var n={};n.src=t.getAttribute("src"),n.srcset=t.getAttribute("srcset"),n.sizes=t.getAttribute("sizes"),t.llOriginalAttrs=n}},x=function(t){if(O(t)){var n=t.llOriginalAttrs;z(t,"src",n.src),z(t,"srcset",n.srcset),z(t,"sizes",n.sizes)}},M=function(t,n){z(t,"sizes",s(t,n.data_sizes)),z(t,"srcset",s(t,n.data_srcset)),z(t,"src",s(t,n.data_src))},R=function(t){C(t,"src"),C(t,"srcset"),C(t,"sizes")},T=function(t,n){var e=t.parentNode;e&&"PICTURE"===e.tagName&&w(e).forEach(n)},G={IMG:function(t,n){T(t,(function(t){N(t),M(t,n)})),N(t),M(t,n)},IFRAME:function(t,n){z(t,"src",s(t,n.data_src))},VIDEO:function(t,n){w(t).forEach((function(t){z(t,"src",s(t,n.data_src))})),z(t,"poster",s(t,n.data_poster)),z(t,"src",s(t,n.data_src)),t.load()}},S=function(t,n,e){var i=G[t.tagName];i&&(i(t,n),A(e),y(t,n.class_loading),f(t,"loading"),E(n.callback_loading,t,e),E(n.callback_reveal,t,e))},D=["IMG","IFRAME","VIDEO"],F=function(t){t&&(t.loadingCount-=1)},P=function(t,n){!n||n.toLoadCount||n.loadingCount||E(t.callback_finish,n)},V=function(t,n,e){t.addEventListener(n,e),t.llEvLisnrs[n]=e},j=function(t,n,e){t.removeEventListener(n,e)},U=function(t){return!!t.llEvLisnrs},$=function(t){if(U(t)){var n=t.llEvLisnrs;for(var e in n){var i=n[e];j(t,e,i)}delete t.llEvLisnrs}},q=function(t,n,e){!function(t){delete t.llTempImage}(t),F(e),L(t,n.class_loading),k(t,n,e)},H=function(t,n,e){var i=I(t)||t;if(!U(i)){!function(t,n,e){U(t)||(t.llEvLisnrs={}),V(t,"load",n),V(t,"error",e),"VIDEO"===t.tagName&&V(t,"loadeddata",n)}(i,(function(a){!function(t,n,e,i){q(n,e,i),y(n,e.class_loaded),f(n,"loaded"),E(e.callback_loaded,n,i),P(e,i)}(0,t,n,e),$(i)}),(function(a){!function(t,n,e,i){q(n,e,i),y(n,e.class_error),f(n,"error"),E(e.callback_error,n,i),P(e,i)}(0,t,n,e),$(i)}))}},B=function(t){t&&(t.toLoadCount-=1)},J=function(t,n,e){!function(t){t.llTempImage=document.createElement("img")}(t),H(t,n,e),function(t,n,e){var i=s(t,n.data_bg),a=s(t,n.data_bg_hidpi),r=o&&a?a:i;r&&(t.style.backgroundImage='url("'.concat(r,'")'),I(t).setAttribute("src",r),A(e),y(t,n.class_loading),f(t,"loading"),E(n.callback_loading,t,e),E(n.callback_reveal,t,e))}(t,n,e),function(t,n,e){var i=s(t,n.data_bg_multi),a=s(t,n.data_bg_multi_hidpi),r=o&&a?a:i;r&&(t.style.backgroundImage=r,y(t,n.class_applied),f(t,"applied"),k(t,n,e),E(n.callback_applied,t,e))}(t,n,e)},K=function(t,n,e){!function(t){return D.indexOf(t.tagName)>-1}(t)?J(t,n,e):function(t,n,e){H(t,n,e),S(t,n,e)}(t,n,e),B(e),P(n,e)},Q=function(t){var n=m(t);n&&(v(t)&&_(t),clearTimeout(n),h(t,null))},W=function(t,n,e,i){"IMG"===t.tagName&&($(t),function(t){T(t,(function(t){R(t)})),R(t)}(t),function(t){T(t,(function(t){x(t)})),x(t)}(t),L(t,e.class_loading),F(i),E(e.callback_cancel,t,n,i),setTimeout((function(){i.resetElementStatus(t,i)}),0))},X=function(t,n,e,i){E(e.callback_enter,t,n,i),p(t)||(e.load_delay?function(t,n,e){var i=n.load_delay,a=m(t);a||(a=setTimeout((function(){K(t,n,e),Q(t)}),i),f(t,"delayed"),h(t,a))}(t,e,i):K(t,e,i))},Y=function(t,n,e,i){g(t)||(e.cancel_on_exit&&function(t){return"loading"===d(t)}(t)&&W(t,n,e,i),E(e.callback_exit,t,n,i),e.load_delay&&v(t)&&Q(t))},Z=["IMG","IFRAME"],tt=function(t){return t.use_native&&"loading"in HTMLImageElement.prototype},nt=function(t,n,e){t.forEach((function(t){-1!==Z.indexOf(t.tagName)&&(t.setAttribute("loading","lazy"),function(t,n,e){H(t,n,e),S(t,n,e),B(e),f(t,"native"),P(n,e)}(t,n,e))})),e.toLoadCount=0},et=function(t){var n=t._settings;i&&!tt(t._settings)&&(t._observer=new IntersectionObserver((function(e){!function(t,n,e){t.forEach((function(t){return function(t){return t.isIntersecting||t.intersectionRatio>0}(t)?X(t.target,t,n,e):Y(t.target,t,n,e)}))}(e,n,t)}),function(t){return{root:t.container===document?null:t.container,rootMargin:t.thresholds||t.threshold+"px"}}(n)))},it=function(t){return Array.prototype.slice.call(t)},at=function(t){return t.container.querySelectorAll(t.elements_selector)},ot=function(t){return function(t){return"error"===d(t)}(t)},rt=function(t,n){return function(t){return it(t).filter(g)}(t||at(n))},ct=function(t){var n,e=t._settings;(n=at(e),it(n).filter(ot)).forEach((function(t){L(t,e.class_error),_(t)})),t.update()},lt=function(t,e){var i;this._settings=c(t),this.loadingCount=0,et(this),i=this,n&&window.addEventListener("online",(function(t){ct(i)})),this.update(e)};return lt.prototype={update:function(t){var n,a,o=this._settings,r=rt(t,o);(this.toLoadCount=r.length,!e&&i)?tt(o)?nt(r,o,this):(n=this._observer,a=r,function(t){t.disconnect()}(n),function(t,n){n.forEach((function(n){t.observe(n)}))}(n,a)):this.loadAll(r)},destroy:function(){this._observer&&this._observer.disconnect(),delete this._observer,delete this._settings,delete this.loadingCount,delete this.toLoadCount},loadAll:function(t){var n=this,e=this._settings;rt(t,e).forEach((function(t){K(t,e,n)}))},resetElementStatus:function(t){!function(t,n){p(t)&&function(t){t&&(t.toLoadCount+=1)}(n),f(t,null)}(t,this)},load:function(t){K(t,this._settings,this)}},lt.load=function(t,n){var e=c(n);K(t,e)},n&&function(t,n){if(n)if(n.length)for(var e,i=0;e=n[i];i+=1)l(t,e);else l(t,n)}(lt,window.lazyLoadOptions),lt}(); | ||
var LazyLoad=function(){"use strict";function t(){return(t=Object.assign||function(t){for(var n=1;n<arguments.length;n++){var e=arguments[n];for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])}return t}).apply(this,arguments)}var n="undefined"!=typeof window,e=n&&!("onscroll"in window)||"undefined"!=typeof navigator&&/(gle|ing|ro)bot|crawl|spider/i.test(navigator.userAgent),i=n&&"IntersectionObserver"in window,a=n&&"classList"in document.createElement("p"),o=n&&window.devicePixelRatio>1,r={elements_selector:"img",container:e||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_poster:"poster",class_applied:"applied",class_loading:"loading",class_loaded:"loaded",class_error:"error",unobserve_completed:!0,unobserve_entered:!1,cancel_on_exit:!1,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},c=function(n){return t({},r,n)},l=function(t,n){var e,i=new t(n);try{e=new CustomEvent("LazyLoad::Initialized",{detail:{instance:i}})}catch(t){(e=document.createEvent("CustomEvent")).initCustomEvent("LazyLoad::Initialized",!1,!1,{instance:i})}window.dispatchEvent(e)},s=function(t,n){return t.getAttribute("data-"+n)},u=function(t){return s(t,"ll-status")},d=function(t,n){return function(t,n,e){var i="data-"+n;null!==e?t.setAttribute(i,e):t.removeAttribute(i)}(t,"ll-status",n)},f=function(t){return d(t,null)},_=function(t){return null===u(t)},g=["loading","applied","loaded","error"],v=function(t,n,e,i){t&&(void 0===i?void 0===e?t(n):t(n,e):t(n,e,i))},b=function(t,n){a?t.classList.add(n):t.className+=(t.className?" ":"")+n},p=function(t,n){a?t.classList.remove(n):t.className=t.className.replace(new RegExp("(^|\\s+)"+n+"(\\s+|$)")," ").replace(/^\s+/,"").replace(/\s+$/,"")},h=function(t){return t.llTempImage},m=function(t,n){if(n){var e=n._observer;e&&e.unobserve(t)}},E=function(t,n){t&&(t.loadingCount+=n)},L=function(t,n){t&&(t.toLoadCount=n)},I=function(t){for(var n,e=[],i=0;n=t.children[i];i+=1)"SOURCE"===n.tagName&&e.push(n);return e},A=function(t,n,e){e&&t.setAttribute(n,e)},w=function(t,n){t.removeAttribute(n)},k=function(t){return!!t.llOriginalAttrs},y=function(t){if(!k(t)){var n={};n.src=t.getAttribute("src"),n.srcset=t.getAttribute("srcset"),n.sizes=t.getAttribute("sizes"),t.llOriginalAttrs=n}},z=function(t){if(k(t)){var n=t.llOriginalAttrs;A(t,"src",n.src),A(t,"srcset",n.srcset),A(t,"sizes",n.sizes)}},O=function(t,n){A(t,"sizes",s(t,n.data_sizes)),A(t,"srcset",s(t,n.data_srcset)),A(t,"src",s(t,n.data_src))},C=function(t){w(t,"src"),w(t,"srcset"),w(t,"sizes")},N=function(t,n){var e=t.parentNode;e&&"PICTURE"===e.tagName&&I(e).forEach(n)},x={IMG:function(t,n){N(t,(function(t){y(t),O(t,n)})),y(t),O(t,n)},IFRAME:function(t,n){A(t,"src",s(t,n.data_src))},VIDEO:function(t,n){I(t).forEach((function(t){A(t,"src",s(t,n.data_src))})),A(t,"poster",s(t,n.data_poster)),A(t,"src",s(t,n.data_src)),t.load()}},M=function(t,n,e){var i=x[t.tagName];i&&(i(t,n),E(e,1),b(t,n.class_loading),d(t,"loading"),v(n.callback_loading,t,e))},R=["IMG","IFRAME","VIDEO"],T=function(t,n){!n||function(t){return t.loadingCount>0}(n)||function(t){return t.toLoadCount>0}(n)||v(t.callback_finish,n)},G=function(t,n,e){t.addEventListener(n,e),t.llEvLisnrs[n]=e},D=function(t,n,e){t.removeEventListener(n,e)},F=function(t){return!!t.llEvLisnrs},P=function(t){if(F(t)){var n=t.llEvLisnrs;for(var e in n){var i=n[e];D(t,e,i)}delete t.llEvLisnrs}},S=function(t,n,e){!function(t){delete t.llTempImage}(t),E(e,-1),function(t){t&&(t.toLoadCount-=1)}(e),p(t,n.class_loading),n.unobserve_completed&&m(t,e)},V=function(t,n,e){var i=h(t)||t;if(!F(i)){!function(t,n,e){F(t)||(t.llEvLisnrs={}),G(t,"load",n),G(t,"error",e),"VIDEO"===t.tagName&&G(t,"loadeddata",n)}(i,(function(a){!function(t,n,e,i){S(n,e,i),b(n,e.class_loaded),d(n,"loaded"),v(e.callback_loaded,n,i),T(e,i)}(0,t,n,e),P(i)}),(function(a){!function(t,n,e,i){S(n,e,i),b(n,e.class_error),d(n,"error"),v(e.callback_error,n,i),T(e,i)}(0,t,n,e),P(i)}))}},j=function(t,n,e){!function(t){t.llTempImage=document.createElement("img")}(t),V(t,n,e),function(t,n,e){var i=s(t,n.data_bg),a=s(t,n.data_bg_hidpi),r=o&&a?a:i;r&&(t.style.backgroundImage='url("'.concat(r,'")'),h(t).setAttribute("src",r),E(e,1),b(t,n.class_loading),d(t,"loading"),v(n.callback_loading,t,e))}(t,n,e),function(t,n,e){var i=s(t,n.data_bg_multi),a=s(t,n.data_bg_multi_hidpi),r=o&&a?a:i;r&&(t.style.backgroundImage=r,b(t,n.class_applied),d(t,"applied"),v(n.callback_applied,t,e),n.unobserve_completed&&m(t,n))}(t,n,e)},U=function(t,n,e){!function(t){return R.indexOf(t.tagName)>-1}(t)?j(t,n,e):function(t,n,e){V(t,n,e),M(t,n,e)}(t,n,e),T(n,e)},$=function(t,n,e,i){"IMG"===t.tagName&&(P(t),function(t){N(t,(function(t){C(t)})),C(t)}(t),function(t){N(t,(function(t){z(t)})),z(t)}(t),p(t,e.class_loading),E(i,-1),v(e.callback_cancel,t,n,i),setTimeout((function(){f(t)}),0))},q=function(t,n,e,i){v(e.callback_enter,t,n,i),function(t){return g.indexOf(u(t))>-1}(t)||(e.unobserve_entered&&m(t,i),U(t,e,i))},H=function(t,n,e,i){_(t)||(e.cancel_on_exit&&function(t){return"loading"===u(t)}(t)&&$(t,n,e,i),v(e.callback_exit,t,n,i))},B=["IMG","IFRAME"],J=function(t){return t.use_native&&"loading"in HTMLImageElement.prototype},K=function(t,n,e){t.forEach((function(t){-1!==B.indexOf(t.tagName)&&(t.setAttribute("loading","lazy"),function(t,n,e){V(t,n,e),M(t,n,e),d(t,"native"),T(n,e)}(t,n,e))})),L(e,0)},Q=function(t,n){i&&!J(t)&&(n._observer=new IntersectionObserver((function(e){!function(t,n,e){t.forEach((function(t){return function(t){return t.isIntersecting||t.intersectionRatio>0}(t)?q(t.target,t,n,e):H(t.target,t,n,e)}))}(e,t,n)}),function(t){return{root:t.container===document?null:t.container,rootMargin:t.thresholds||t.threshold+"px"}}(t)))},W=function(t){return Array.prototype.slice.call(t)},X=function(t){return t.container.querySelectorAll(t.elements_selector)},Y=function(t){return function(t){return"error"===u(t)}(t)},Z=function(t,n){return function(t){return W(t).filter(_)}(t||X(n))},tt=function(t,n){var e;(e=X(t),W(e).filter(Y)).forEach((function(n){p(n,t.class_error),f(n)})),n.update()},nt=function(t,e){var i=c(t);this._settings=i,this.loadingCount=0,Q(i,this),function(t,e){n&&window.addEventListener("online",(function(){tt(t,e)}))}(i,this),this.update(e)};return nt.prototype={update:function(t){var n,a,o=this._settings,r=Z(t,o);(L(this,r.length),!e&&i)?J(o)?K(r,o,this):(n=this._observer,a=r,function(t){t.disconnect()}(n),function(t,n){n.forEach((function(n){t.observe(n)}))}(n,a)):this.loadAll(r)},destroy:function(){this._observer&&this._observer.disconnect(),delete this._observer,delete this._settings,delete this.loadingCount,delete this.toLoadCount},loadAll:function(t){var n=this,e=this._settings;Z(t,e).forEach((function(t){U(t,e,n)}))}},nt.load=function(t,n){var e=c(n);U(t,e)},nt.resetStatus=function(t){f(t)},n&&function(t,n){if(n)if(n.length)for(var e,i=0;e=n[i];i+=1)l(t,e);else l(t,n)}(nt,window.lazyLoadOptions),nt}(); |
@@ -48,4 +48,4 @@ (function (global, factory) { | ||
class_error: "error", | ||
load_delay: 0, | ||
auto_unobserve: true, | ||
unobserve_completed: true, | ||
unobserve_entered: false, | ||
cancel_on_exit: false, | ||
@@ -109,3 +109,2 @@ callback_enter: null, | ||
var statusDelayed = "delayed"; | ||
var statusLoading = "loading"; | ||
@@ -119,3 +118,2 @@ var statusLoaded = "loaded"; | ||
var statusDataName = "ll-status"; | ||
var timeoutDataName = "ll-timeout"; | ||
var getData = function getData(element, attribute) { | ||
@@ -152,5 +150,2 @@ return element.getAttribute(dataPrefix + attribute); | ||
}; | ||
var hasStatusDelayed = function hasStatusDelayed(element) { | ||
return getStatus(element) === statusDelayed; | ||
}; | ||
var statusesAfterLoading = [statusLoading, statusApplied, statusLoaded, statusError]; | ||
@@ -160,8 +155,2 @@ var hasStatusAfterLoading = function hasStatusAfterLoading(element) { | ||
}; | ||
var setTimeoutData = function setTimeoutData(element, value) { | ||
return setData(element, timeoutDataName, value); | ||
}; | ||
var getTimeoutData = function getTimeoutData(element) { | ||
return getData(element, timeoutDataName); | ||
}; | ||
@@ -213,6 +202,6 @@ var safeCallback = function safeCallback(callback, arg1, arg2, arg3) { | ||
var unobserve = function unobserve(element, settings, instance) { | ||
var unobserve = function unobserve(element, instance) { | ||
if (!instance) return; | ||
var observer = instance._observer; | ||
if (!observer || !settings.auto_unobserve) return; | ||
if (!observer) return; | ||
observer.unobserve(element); | ||
@@ -224,2 +213,21 @@ }; | ||
var updateLoadingCount = function updateLoadingCount(instance, delta) { | ||
if (!instance) return; | ||
instance.loadingCount += delta; | ||
}; | ||
var decreaseToLoadCount = function decreaseToLoadCount(instance) { | ||
if (!instance) return; | ||
instance.toLoadCount -= 1; | ||
}; | ||
var setToLoadCount = function 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; | ||
}; | ||
var _src_ = "src"; | ||
@@ -230,6 +238,2 @@ var _srcset_ = "srcset"; | ||
var _PICTURE_ = "PICTURE"; | ||
var increaseLoadingCount = function increaseLoadingCount(instance) { | ||
if (!instance) return; | ||
instance.loadingCount += 1; | ||
}; | ||
var getSourceTags = function getSourceTags(parentTag) { | ||
@@ -260,3 +264,6 @@ var sourceTags = []; | ||
var saveOriginalImageAttributes = function saveOriginalImageAttributes(element) { | ||
if (hasOriginalAttributes(element)) return; | ||
if (hasOriginalAttributes(element)) { | ||
return; | ||
} | ||
var originalAttributes = {}; | ||
@@ -269,3 +276,6 @@ originalAttributes[_src_] = element.getAttribute(_src_); | ||
var restoreOriginalImageAttributes = function restoreOriginalImageAttributes(element) { | ||
if (!hasOriginalAttributes(element)) return; | ||
if (!hasOriginalAttributes(element)) { | ||
return; | ||
} | ||
var originalAttributes = element.llOriginalAttrs; | ||
@@ -288,3 +298,7 @@ setAttributeIfValue(element, _src_, originalAttributes[_src_]); | ||
var parent = element.parentNode; | ||
if (!parent || parent.tagName !== _PICTURE_) return; | ||
if (!parent || parent.tagName !== _PICTURE_) { | ||
return; | ||
} | ||
var sourceTags = getSourceTags(parent); | ||
@@ -338,7 +352,6 @@ sourceTags.forEach(fn); | ||
increaseLoadingCount(instance); | ||
updateLoadingCount(instance, +1); | ||
addClass(element, settings.class_loading); | ||
setStatus(element, statusLoading); | ||
safeCallback(settings.callback_loading, element, instance); | ||
safeCallback(settings.callback_reveal, element, instance); // <== DEPRECATED | ||
}; // NOTE: THE TEMP IMAGE TRICK CANNOT BE DONE WITH data-multi-bg | ||
@@ -352,3 +365,7 @@ // BECAUSE INSIDE ITS VALUES MUST BE WRAPPED WITH URL() AND ONE OF THEM | ||
var bgDataValue = isHiDpi && bgHiDpiValue ? bgHiDpiValue : bg1xValue; | ||
if (!bgDataValue) return; | ||
if (!bgDataValue) { | ||
return; | ||
} | ||
element.style.backgroundImage = bgDataValue; // Annotate and notify applied | ||
@@ -358,16 +375,22 @@ | ||
setStatus(element, statusApplied); | ||
unobserve(element, settings, instance); // Unobserve here because we can't do it on load | ||
safeCallback(settings.callback_applied, element, instance); | ||
safeCallback(settings.callback_applied, element, instance); | ||
if (settings.unobserve_completed) { | ||
// Unobserve now because we can't do it on load | ||
unobserve(element, settings); | ||
} | ||
}; | ||
var setSources = function setSources(element, settings, instance) { | ||
var setSourcesFunction = setSourcesFunctions[element.tagName]; | ||
if (!setSourcesFunction) return; | ||
if (!setSourcesFunction) { | ||
return; | ||
} | ||
setSourcesFunction(element, settings); // Annotate and notify loading | ||
increaseLoadingCount(instance); | ||
updateLoadingCount(instance, +1); | ||
addClass(element, settings.class_loading); | ||
setStatus(element, statusLoading); | ||
safeCallback(settings.callback_loading, element, instance); | ||
safeCallback(settings.callback_reveal, element, instance); // <== DEPRECATED | ||
}; | ||
@@ -382,9 +405,6 @@ | ||
}; | ||
var decreaseLoadingCount = function decreaseLoadingCount(instance) { | ||
if (!instance) return; | ||
instance.loadingCount -= 1; | ||
}; | ||
var checkFinish = function checkFinish(settings, instance) { | ||
if (!instance || instance.toLoadCount || instance.loadingCount) return; | ||
safeCallback(settings.callback_finish, instance); | ||
if (instance && !isSomethingLoading(instance) && !haveElementsToLoad(instance)) { | ||
safeCallback(settings.callback_finish, instance); | ||
} | ||
}; | ||
@@ -405,7 +425,12 @@ var addEventListener = function addEventListener(element, eventName, handler) { | ||
addEventListener(element, errorEventName, errorHandler); | ||
if (element.tagName !== "VIDEO") return; | ||
addEventListener(element, mediaLoadEventName, loadHandler); | ||
if (element.tagName === "VIDEO") { | ||
addEventListener(element, mediaLoadEventName, loadHandler); | ||
} | ||
}; | ||
var removeEventListeners = function removeEventListeners(element) { | ||
if (!hasEventListeners(element)) return; | ||
if (!hasEventListeners(element)) { | ||
return; | ||
} | ||
var eventListeners = element.llEvLisnrs; | ||
@@ -422,5 +447,9 @@ | ||
deleteTempImage(element); | ||
decreaseLoadingCount(instance); | ||
updateLoadingCount(instance, -1); | ||
decreaseToLoadCount(instance); | ||
removeClass(element, settings.class_loading); | ||
unobserve(element, settings, instance); | ||
if (settings.unobserve_completed) { | ||
unobserve(element, instance); | ||
} | ||
}; | ||
@@ -443,4 +472,8 @@ var loadHandler = function loadHandler(event, element, settings, instance) { | ||
var elementToListenTo = getTempImage(element) || element; | ||
if (hasEventListeners(elementToListenTo)) return; // <- when retry loading, e.g. with cancel_on_exit | ||
if (hasEventListeners(elementToListenTo)) { | ||
// This happens when loading is retried twice | ||
return; | ||
} | ||
var _loadHandler = function _loadHandler(event) { | ||
@@ -459,11 +492,2 @@ loadHandler(event, element, settings, instance); | ||
var decreaseToLoadCount = function decreaseToLoadCount(instance) { | ||
if (!instance) return; | ||
instance.toLoadCount -= 1; | ||
}; | ||
var increaseToLoadCount = function increaseToLoadCount(instance) { | ||
if (!instance) return; | ||
instance.toLoadCount += 1; | ||
}; | ||
var loadBackground = function loadBackground(element, settings, instance) { | ||
@@ -488,3 +512,2 @@ addTempImage(element); | ||
decreaseToLoadCount(instance); | ||
checkFinish(settings, instance); | ||
@@ -495,3 +518,2 @@ }; | ||
setSources(element, settings, instance); | ||
decreaseToLoadCount(instance); | ||
setStatus(element, statusNative); | ||
@@ -501,35 +523,8 @@ checkFinish(settings, instance); | ||
var cancelDelayLoad = function cancelDelayLoad(element) { | ||
var timeoutId = getTimeoutData(element); | ||
if (!timeoutId) { | ||
return; // do nothing if timeout doesn't exist | ||
var cancelIfLoading = function cancelIfLoading(element, entry, settings, instance) { | ||
if (element.tagName !== "IMG") { | ||
// Can't cancel loading on anything but images | ||
return; | ||
} | ||
if (hasStatusDelayed(element)) { | ||
// iffing because status could also be "loading" | ||
resetStatus(element); | ||
} | ||
clearTimeout(timeoutId); | ||
setTimeoutData(element, null); | ||
}; | ||
var delayLoad = function delayLoad(element, settings, instance) { | ||
var loadDelay = settings.load_delay; | ||
var timeoutId = getTimeoutData(element); | ||
if (timeoutId) { | ||
return; // do nothing if timeout already set | ||
} | ||
timeoutId = setTimeout(function () { | ||
load(element, settings, instance); | ||
cancelDelayLoad(element); | ||
}, loadDelay); | ||
setStatus(element, statusDelayed); | ||
setTimeoutData(element, timeoutId); | ||
}; | ||
var cancelIfLoading = function cancelIfLoading(element, entry, settings, instance) { | ||
if (element.tagName !== "IMG") return; | ||
removeEventListeners(element); | ||
@@ -539,3 +534,3 @@ resetSourcesImg(element); | ||
removeClass(element, settings.class_loading); | ||
decreaseLoadingCount(instance); | ||
updateLoadingCount(instance, -1); | ||
safeCallback(settings.callback_cancel, element, entry, instance); // setTimeout is needed because the "callback_cancel" implementation | ||
@@ -545,19 +540,23 @@ // could be out of the main thread, e.g. `img.setAttribute("src", "")` | ||
setTimeout(function () { | ||
instance.resetElementStatus(element, instance); | ||
resetStatus(element); | ||
}, 0); | ||
}; | ||
var onIntersecting = function onIntersecting(element, entry, settings, instance) { | ||
var onEnter = function onEnter(element, entry, settings, instance) { | ||
safeCallback(settings.callback_enter, element, entry, instance); | ||
if (hasStatusAfterLoading(element)) return; //Prevent loading it again, e.g. on !auto_unobserve | ||
if (settings.load_delay) { | ||
delayLoad(element, settings, instance); | ||
return; | ||
if (hasStatusAfterLoading(element)) { | ||
return; //Prevent loading it again | ||
} | ||
if (settings.unobserve_entered) { | ||
unobserve(element, instance); | ||
} | ||
load(element, settings, instance); | ||
}; | ||
var onNotIntersecting = function onNotIntersecting(element, entry, settings, instance) { | ||
if (hasEmptyStatus(element)) return; //Ignore the first pass at landing | ||
var onExit = function onExit(element, entry, settings, instance) { | ||
if (hasEmptyStatus(element)) { | ||
return; //Ignore the first pass, at landing | ||
} | ||
@@ -569,6 +568,2 @@ if (settings.cancel_on_exit && hasStatusLoading(element)) { | ||
safeCallback(settings.callback_exit, element, entry, instance); | ||
if (settings.load_delay && hasStatusDelayed(element)) { | ||
cancelDelayLoad(element); | ||
} | ||
}; | ||
@@ -591,3 +586,3 @@ | ||
}); | ||
instance.toLoadCount = 0; | ||
setToLoadCount(instance, 0); | ||
}; | ||
@@ -608,3 +603,3 @@ | ||
entries.forEach(function (entry) { | ||
return isIntersecting(entry) ? onIntersecting(entry.target, entry, settings, instance) : onNotIntersecting(entry.target, entry, settings, instance); | ||
return isIntersecting(entry) ? onEnter(entry.target, entry, settings, instance) : onExit(entry.target, entry, settings, instance); | ||
}); | ||
@@ -622,6 +617,4 @@ }; | ||
}; | ||
var setObserver = function setObserver(instance) { | ||
var settings = instance._settings; | ||
if (!supportsIntersectionObserver || shouldUseNative(instance._settings)) { | ||
var setObserver = function setObserver(settings, instance) { | ||
if (!supportsIntersectionObserver || shouldUseNative(settings)) { | ||
return; | ||
@@ -654,4 +647,3 @@ } | ||
var retryLazyLoad = function retryLazyLoad(instance) { | ||
var settings = instance._settings; | ||
var retryLazyLoad = function retryLazyLoad(settings, instance) { | ||
var errorElements = filterErrorElements(queryElements(settings)); | ||
@@ -664,3 +656,3 @@ errorElements.forEach(function (element) { | ||
}; | ||
var setOnlineCheck = function setOnlineCheck(instance) { | ||
var setOnlineCheck = function setOnlineCheck(settings, instance) { | ||
if (!runningOnBrowser) { | ||
@@ -670,20 +662,13 @@ return; | ||
window.addEventListener("online", function (event) { | ||
retryLazyLoad(instance); | ||
window.addEventListener("online", function () { | ||
retryLazyLoad(settings, instance); | ||
}); | ||
}; | ||
var resetElementStatus = function resetElementStatus(element, instance) { | ||
if (hasStatusAfterLoading(element)) { | ||
increaseToLoadCount(instance); | ||
} | ||
setStatus(element, null); | ||
}; | ||
var LazyLoad = function LazyLoad(customSettings, elements) { | ||
this._settings = getExtendedSettings(customSettings); | ||
var settings = getExtendedSettings(customSettings); | ||
this._settings = settings; | ||
this.loadingCount = 0; | ||
setObserver(this); | ||
setOnlineCheck(this); | ||
setObserver(settings, this); | ||
setOnlineCheck(settings, this); | ||
this.update(elements); | ||
@@ -696,3 +681,3 @@ }; | ||
var elementsToLoad = getElementsToLoad(givenNodeset, settings); | ||
this.toLoadCount = elementsToLoad.length; | ||
setToLoadCount(this, elementsToLoad.length); | ||
@@ -730,9 +715,2 @@ if (isBot || !supportsIntersectionObserver) { | ||
}); | ||
}, | ||
resetElementStatus: function resetElementStatus$1(element) { | ||
resetElementStatus(element, this); | ||
}, | ||
// DEPRECATED | ||
load: function load$1(element) { | ||
load(element, this._settings, this); | ||
} | ||
@@ -743,4 +721,7 @@ }; | ||
var settings = getExtendedSettings(customSettings); | ||
load(element, settings); | ||
}; | ||
load(element, settings); | ||
LazyLoad.resetStatus = function (element) { | ||
resetStatus(element); | ||
}; // Automatic instances creation if required (useful for async script loading) | ||
@@ -747,0 +728,0 @@ |
@@ -1,1 +0,1 @@ | ||
!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):(t=t||self).LazyLoad=n()}(this,(function(){"use strict";function t(){return(t=Object.assign||function(t){for(var n=1;n<arguments.length;n++){var e=arguments[n];for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])}return t}).apply(this,arguments)}var n="undefined"!=typeof window,e=n&&!("onscroll"in window)||"undefined"!=typeof navigator&&/(gle|ing|ro)bot|crawl|spider/i.test(navigator.userAgent),i=n&&"IntersectionObserver"in window,o=n&&"classList"in document.createElement("p"),a=n&&window.devicePixelRatio>1,r={elements_selector:"img",container:e||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_poster:"poster",class_applied:"applied",class_loading:"loading",class_loaded:"loaded",class_error:"error",load_delay:0,auto_unobserve:!0,cancel_on_exit:!1,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},c=function(n){return t({},r,n)},l=function(t,n){var e,i=new t(n);try{e=new CustomEvent("LazyLoad::Initialized",{detail:{instance:i}})}catch(t){(e=document.createEvent("CustomEvent")).initCustomEvent("LazyLoad::Initialized",!1,!1,{instance:i})}window.dispatchEvent(e)},s=function(t,n){return t.getAttribute("data-"+n)},u=function(t,n,e){var i="data-"+n;null!==e?t.setAttribute(i,e):t.removeAttribute(i)},d=function(t){return s(t,"ll-status")},f=function(t,n){return u(t,"ll-status",n)},_=function(t){return f(t,null)},g=function(t){return null===d(t)},v=function(t){return"delayed"===d(t)},b=["loading","applied","loaded","error"],p=function(t){return b.indexOf(d(t))>-1},m=function(t,n){return u(t,"ll-timeout",n)},h=function(t){return s(t,"ll-timeout")},E=function(t,n,e,i){t&&(void 0===i?void 0===e?t(n):t(n,e):t(n,e,i))},y=function(t,n){o?t.classList.add(n):t.className+=(t.className?" ":"")+n},L=function(t,n){o?t.classList.remove(n):t.className=t.className.replace(new RegExp("(^|\\s+)"+n+"(\\s+|$)")," ").replace(/^\s+/,"").replace(/\s+$/,"")},I=function(t){return t.llTempImage},k=function(t,n,e){if(e){var i=e._observer;i&&n.auto_unobserve&&i.unobserve(t)}},A=function(t){t&&(t.loadingCount+=1)},w=function(t){for(var n,e=[],i=0;n=t.children[i];i+=1)"SOURCE"===n.tagName&&e.push(n);return e},z=function(t,n,e){e&&t.setAttribute(n,e)},C=function(t,n){t.removeAttribute(n)},O=function(t){return!!t.llOriginalAttrs},x=function(t){if(!O(t)){var n={};n.src=t.getAttribute("src"),n.srcset=t.getAttribute("srcset"),n.sizes=t.getAttribute("sizes"),t.llOriginalAttrs=n}},N=function(t){if(O(t)){var n=t.llOriginalAttrs;z(t,"src",n.src),z(t,"srcset",n.srcset),z(t,"sizes",n.sizes)}},M=function(t,n){z(t,"sizes",s(t,n.data_sizes)),z(t,"srcset",s(t,n.data_srcset)),z(t,"src",s(t,n.data_src))},R=function(t){C(t,"src"),C(t,"srcset"),C(t,"sizes")},T=function(t,n){var e=t.parentNode;e&&"PICTURE"===e.tagName&&w(e).forEach(n)},G={IMG:function(t,n){T(t,(function(t){x(t),M(t,n)})),x(t),M(t,n)},IFRAME:function(t,n){z(t,"src",s(t,n.data_src))},VIDEO:function(t,n){w(t).forEach((function(t){z(t,"src",s(t,n.data_src))})),z(t,"poster",s(t,n.data_poster)),z(t,"src",s(t,n.data_src)),t.load()}},S=function(t,n,e){var i=G[t.tagName];i&&(i(t,n),A(e),y(t,n.class_loading),f(t,"loading"),E(n.callback_loading,t,e),E(n.callback_reveal,t,e))},j=["IMG","IFRAME","VIDEO"],D=function(t){t&&(t.loadingCount-=1)},F=function(t,n){!n||n.toLoadCount||n.loadingCount||E(t.callback_finish,n)},P=function(t,n,e){t.addEventListener(n,e),t.llEvLisnrs[n]=e},V=function(t,n,e){t.removeEventListener(n,e)},U=function(t){return!!t.llEvLisnrs},$=function(t){if(U(t)){var n=t.llEvLisnrs;for(var e in n){var i=n[e];V(t,e,i)}delete t.llEvLisnrs}},q=function(t,n,e){!function(t){delete t.llTempImage}(t),D(e),L(t,n.class_loading),k(t,n,e)},H=function(t,n,e){var i=I(t)||t;if(!U(i)){!function(t,n,e){U(t)||(t.llEvLisnrs={}),P(t,"load",n),P(t,"error",e),"VIDEO"===t.tagName&&P(t,"loadeddata",n)}(i,(function(o){!function(t,n,e,i){q(n,e,i),y(n,e.class_loaded),f(n,"loaded"),E(e.callback_loaded,n,i),F(e,i)}(0,t,n,e),$(i)}),(function(o){!function(t,n,e,i){q(n,e,i),y(n,e.class_error),f(n,"error"),E(e.callback_error,n,i),F(e,i)}(0,t,n,e),$(i)}))}},B=function(t){t&&(t.toLoadCount-=1)},J=function(t,n,e){!function(t){t.llTempImage=document.createElement("img")}(t),H(t,n,e),function(t,n,e){var i=s(t,n.data_bg),o=s(t,n.data_bg_hidpi),r=a&&o?o:i;r&&(t.style.backgroundImage='url("'.concat(r,'")'),I(t).setAttribute("src",r),A(e),y(t,n.class_loading),f(t,"loading"),E(n.callback_loading,t,e),E(n.callback_reveal,t,e))}(t,n,e),function(t,n,e){var i=s(t,n.data_bg_multi),o=s(t,n.data_bg_multi_hidpi),r=a&&o?o:i;r&&(t.style.backgroundImage=r,y(t,n.class_applied),f(t,"applied"),k(t,n,e),E(n.callback_applied,t,e))}(t,n,e)},K=function(t,n,e){!function(t){return j.indexOf(t.tagName)>-1}(t)?J(t,n,e):function(t,n,e){H(t,n,e),S(t,n,e)}(t,n,e),B(e),F(n,e)},Q=function(t){var n=h(t);n&&(v(t)&&_(t),clearTimeout(n),m(t,null))},W=function(t,n,e,i){"IMG"===t.tagName&&($(t),function(t){T(t,(function(t){R(t)})),R(t)}(t),function(t){T(t,(function(t){N(t)})),N(t)}(t),L(t,e.class_loading),D(i),E(e.callback_cancel,t,n,i),setTimeout((function(){i.resetElementStatus(t,i)}),0))},X=function(t,n,e,i){E(e.callback_enter,t,n,i),p(t)||(e.load_delay?function(t,n,e){var i=n.load_delay,o=h(t);o||(o=setTimeout((function(){K(t,n,e),Q(t)}),i),f(t,"delayed"),m(t,o))}(t,e,i):K(t,e,i))},Y=function(t,n,e,i){g(t)||(e.cancel_on_exit&&function(t){return"loading"===d(t)}(t)&&W(t,n,e,i),E(e.callback_exit,t,n,i),e.load_delay&&v(t)&&Q(t))},Z=["IMG","IFRAME"],tt=function(t){return t.use_native&&"loading"in HTMLImageElement.prototype},nt=function(t,n,e){t.forEach((function(t){-1!==Z.indexOf(t.tagName)&&(t.setAttribute("loading","lazy"),function(t,n,e){H(t,n,e),S(t,n,e),B(e),f(t,"native"),F(n,e)}(t,n,e))})),e.toLoadCount=0},et=function(t){var n=t._settings;i&&!tt(t._settings)&&(t._observer=new IntersectionObserver((function(e){!function(t,n,e){t.forEach((function(t){return function(t){return t.isIntersecting||t.intersectionRatio>0}(t)?X(t.target,t,n,e):Y(t.target,t,n,e)}))}(e,n,t)}),function(t){return{root:t.container===document?null:t.container,rootMargin:t.thresholds||t.threshold+"px"}}(n)))},it=function(t){return Array.prototype.slice.call(t)},ot=function(t){return t.container.querySelectorAll(t.elements_selector)},at=function(t){return function(t){return"error"===d(t)}(t)},rt=function(t,n){return function(t){return it(t).filter(g)}(t||ot(n))},ct=function(t){var n,e=t._settings;(n=ot(e),it(n).filter(at)).forEach((function(t){L(t,e.class_error),_(t)})),t.update()},lt=function(t,e){var i;this._settings=c(t),this.loadingCount=0,et(this),i=this,n&&window.addEventListener("online",(function(t){ct(i)})),this.update(e)};return lt.prototype={update:function(t){var n,o,a=this._settings,r=rt(t,a);(this.toLoadCount=r.length,!e&&i)?tt(a)?nt(r,a,this):(n=this._observer,o=r,function(t){t.disconnect()}(n),function(t,n){n.forEach((function(n){t.observe(n)}))}(n,o)):this.loadAll(r)},destroy:function(){this._observer&&this._observer.disconnect(),delete this._observer,delete this._settings,delete this.loadingCount,delete this.toLoadCount},loadAll:function(t){var n=this,e=this._settings;rt(t,e).forEach((function(t){K(t,e,n)}))},resetElementStatus:function(t){!function(t,n){p(t)&&function(t){t&&(t.toLoadCount+=1)}(n),f(t,null)}(t,this)},load:function(t){K(t,this._settings,this)}},lt.load=function(t,n){var e=c(n);K(t,e)},n&&function(t,n){if(n)if(n.length)for(var e,i=0;e=n[i];i+=1)l(t,e);else l(t,n)}(lt,window.lazyLoadOptions),lt})); | ||
!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):(t=t||self).LazyLoad=n()}(this,(function(){"use strict";function t(){return(t=Object.assign||function(t){for(var n=1;n<arguments.length;n++){var e=arguments[n];for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])}return t}).apply(this,arguments)}var n="undefined"!=typeof window,e=n&&!("onscroll"in window)||"undefined"!=typeof navigator&&/(gle|ing|ro)bot|crawl|spider/i.test(navigator.userAgent),i=n&&"IntersectionObserver"in window,o=n&&"classList"in document.createElement("p"),a=n&&window.devicePixelRatio>1,r={elements_selector:"img",container:e||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_poster:"poster",class_applied:"applied",class_loading:"loading",class_loaded:"loaded",class_error:"error",unobserve_completed:!0,unobserve_entered:!1,cancel_on_exit:!1,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},c=function(n){return t({},r,n)},l=function(t,n){var e,i=new t(n);try{e=new CustomEvent("LazyLoad::Initialized",{detail:{instance:i}})}catch(t){(e=document.createEvent("CustomEvent")).initCustomEvent("LazyLoad::Initialized",!1,!1,{instance:i})}window.dispatchEvent(e)},s=function(t,n){return t.getAttribute("data-"+n)},u=function(t){return s(t,"ll-status")},d=function(t,n){return function(t,n,e){var i="data-"+n;null!==e?t.setAttribute(i,e):t.removeAttribute(i)}(t,"ll-status",n)},f=function(t){return d(t,null)},_=function(t){return null===u(t)},g=["loading","applied","loaded","error"],v=function(t,n,e,i){t&&(void 0===i?void 0===e?t(n):t(n,e):t(n,e,i))},p=function(t,n){o?t.classList.add(n):t.className+=(t.className?" ":"")+n},b=function(t,n){o?t.classList.remove(n):t.className=t.className.replace(new RegExp("(^|\\s+)"+n+"(\\s+|$)")," ").replace(/^\s+/,"").replace(/\s+$/,"")},m=function(t){return t.llTempImage},h=function(t,n){if(n){var e=n._observer;e&&e.unobserve(t)}},E=function(t,n){t&&(t.loadingCount+=n)},L=function(t,n){t&&(t.toLoadCount=n)},y=function(t){for(var n,e=[],i=0;n=t.children[i];i+=1)"SOURCE"===n.tagName&&e.push(n);return e},I=function(t,n,e){e&&t.setAttribute(n,e)},A=function(t,n){t.removeAttribute(n)},w=function(t){return!!t.llOriginalAttrs},k=function(t){if(!w(t)){var n={};n.src=t.getAttribute("src"),n.srcset=t.getAttribute("srcset"),n.sizes=t.getAttribute("sizes"),t.llOriginalAttrs=n}},z=function(t){if(w(t)){var n=t.llOriginalAttrs;I(t,"src",n.src),I(t,"srcset",n.srcset),I(t,"sizes",n.sizes)}},O=function(t,n){I(t,"sizes",s(t,n.data_sizes)),I(t,"srcset",s(t,n.data_srcset)),I(t,"src",s(t,n.data_src))},C=function(t){A(t,"src"),A(t,"srcset"),A(t,"sizes")},x=function(t,n){var e=t.parentNode;e&&"PICTURE"===e.tagName&&y(e).forEach(n)},N={IMG:function(t,n){x(t,(function(t){k(t),O(t,n)})),k(t),O(t,n)},IFRAME:function(t,n){I(t,"src",s(t,n.data_src))},VIDEO:function(t,n){y(t).forEach((function(t){I(t,"src",s(t,n.data_src))})),I(t,"poster",s(t,n.data_poster)),I(t,"src",s(t,n.data_src)),t.load()}},M=function(t,n,e){var i=N[t.tagName];i&&(i(t,n),E(e,1),p(t,n.class_loading),d(t,"loading"),v(n.callback_loading,t,e))},R=["IMG","IFRAME","VIDEO"],T=function(t,n){!n||function(t){return t.loadingCount>0}(n)||function(t){return t.toLoadCount>0}(n)||v(t.callback_finish,n)},G=function(t,n,e){t.addEventListener(n,e),t.llEvLisnrs[n]=e},j=function(t,n,e){t.removeEventListener(n,e)},D=function(t){return!!t.llEvLisnrs},F=function(t){if(D(t)){var n=t.llEvLisnrs;for(var e in n){var i=n[e];j(t,e,i)}delete t.llEvLisnrs}},P=function(t,n,e){!function(t){delete t.llTempImage}(t),E(e,-1),function(t){t&&(t.toLoadCount-=1)}(e),b(t,n.class_loading),n.unobserve_completed&&h(t,e)},S=function(t,n,e){var i=m(t)||t;if(!D(i)){!function(t,n,e){D(t)||(t.llEvLisnrs={}),G(t,"load",n),G(t,"error",e),"VIDEO"===t.tagName&&G(t,"loadeddata",n)}(i,(function(o){!function(t,n,e,i){P(n,e,i),p(n,e.class_loaded),d(n,"loaded"),v(e.callback_loaded,n,i),T(e,i)}(0,t,n,e),F(i)}),(function(o){!function(t,n,e,i){P(n,e,i),p(n,e.class_error),d(n,"error"),v(e.callback_error,n,i),T(e,i)}(0,t,n,e),F(i)}))}},V=function(t,n,e){!function(t){t.llTempImage=document.createElement("img")}(t),S(t,n,e),function(t,n,e){var i=s(t,n.data_bg),o=s(t,n.data_bg_hidpi),r=a&&o?o:i;r&&(t.style.backgroundImage='url("'.concat(r,'")'),m(t).setAttribute("src",r),E(e,1),p(t,n.class_loading),d(t,"loading"),v(n.callback_loading,t,e))}(t,n,e),function(t,n,e){var i=s(t,n.data_bg_multi),o=s(t,n.data_bg_multi_hidpi),r=a&&o?o:i;r&&(t.style.backgroundImage=r,p(t,n.class_applied),d(t,"applied"),v(n.callback_applied,t,e),n.unobserve_completed&&h(t,n))}(t,n,e)},U=function(t,n,e){!function(t){return R.indexOf(t.tagName)>-1}(t)?V(t,n,e):function(t,n,e){S(t,n,e),M(t,n,e)}(t,n,e),T(n,e)},$=function(t,n,e,i){"IMG"===t.tagName&&(F(t),function(t){x(t,(function(t){C(t)})),C(t)}(t),function(t){x(t,(function(t){z(t)})),z(t)}(t),b(t,e.class_loading),E(i,-1),v(e.callback_cancel,t,n,i),setTimeout((function(){f(t)}),0))},q=function(t,n,e,i){v(e.callback_enter,t,n,i),function(t){return g.indexOf(u(t))>-1}(t)||(e.unobserve_entered&&h(t,i),U(t,e,i))},H=function(t,n,e,i){_(t)||(e.cancel_on_exit&&function(t){return"loading"===u(t)}(t)&&$(t,n,e,i),v(e.callback_exit,t,n,i))},B=["IMG","IFRAME"],J=function(t){return t.use_native&&"loading"in HTMLImageElement.prototype},K=function(t,n,e){t.forEach((function(t){-1!==B.indexOf(t.tagName)&&(t.setAttribute("loading","lazy"),function(t,n,e){S(t,n,e),M(t,n,e),d(t,"native"),T(n,e)}(t,n,e))})),L(e,0)},Q=function(t,n){i&&!J(t)&&(n._observer=new IntersectionObserver((function(e){!function(t,n,e){t.forEach((function(t){return function(t){return t.isIntersecting||t.intersectionRatio>0}(t)?q(t.target,t,n,e):H(t.target,t,n,e)}))}(e,t,n)}),function(t){return{root:t.container===document?null:t.container,rootMargin:t.thresholds||t.threshold+"px"}}(t)))},W=function(t){return Array.prototype.slice.call(t)},X=function(t){return t.container.querySelectorAll(t.elements_selector)},Y=function(t){return function(t){return"error"===u(t)}(t)},Z=function(t,n){return function(t){return W(t).filter(_)}(t||X(n))},tt=function(t,n){var e;(e=X(t),W(e).filter(Y)).forEach((function(n){b(n,t.class_error),f(n)})),n.update()},nt=function(t,e){var i=c(t);this._settings=i,this.loadingCount=0,Q(i,this),function(t,e){n&&window.addEventListener("online",(function(){tt(t,e)}))}(i,this),this.update(e)};return nt.prototype={update:function(t){var n,o,a=this._settings,r=Z(t,a);(L(this,r.length),!e&&i)?J(a)?K(r,a,this):(n=this._observer,o=r,function(t){t.disconnect()}(n),function(t,n){n.forEach((function(n){t.observe(n)}))}(n,o)):this.loadAll(r)},destroy:function(){this._observer&&this._observer.disconnect(),delete this._observer,delete this._settings,delete this.loadingCount,delete this.toLoadCount},loadAll:function(t){var n=this,e=this._settings;Z(t,e).forEach((function(t){U(t,e,n)}))}},nt.load=function(t,n){var e=c(n);U(t,e)},nt.resetStatus=function(t){f(t)},n&&function(t,n){if(n)if(n.length)for(var e,i=0;e=n[i];i+=1)l(t,e);else l(t,n)}(nt,window.lazyLoadOptions),nt})); |
{ | ||
"name": "vanilla-lazyload", | ||
"version": "15.2.0", | ||
"version": "16.0.0", | ||
"description": "LazyLoad is a lightweight 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 and enables native lazy loading.", | ||
@@ -5,0 +5,0 @@ "main": "dist/lazyload.min.js", |
132
README.md
@@ -147,3 +147,3 @@ LazyLoad is a lightweight 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](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API) API, it supports [responsive images](https://alistapart.com/article/responsive-images-in-practice) and enables native lazy loading. See [notable features](#-notable-features) for more. | ||
The latest, recommended version of LazyLoad is **15.2.0**. | ||
The latest, recommended version of LazyLoad is **16.0.0**. | ||
@@ -165,3 +165,3 @@ Quickly understand how to upgrade from a previous version reading the [practical upgrade guide](UPGRADE.md). | ||
```html | ||
<script src="https://cdn.jsdelivr.net/npm/vanilla-lazyload@15.2.0/dist/lazyload.min.js"></script> | ||
<script src="https://cdn.jsdelivr.net/npm/vanilla-lazyload@16.0.0/dist/lazyload.min.js"></script> | ||
``` | ||
@@ -173,3 +173,3 @@ | ||
<script src="https://cdn.jsdelivr.net/npm/intersection-observer@0.7.0/intersection-observer.js"></script> | ||
<script src="https://cdn.jsdelivr.net/npm/vanilla-lazyload@15.2.0/dist/lazyload.min.js"></script> | ||
<script src="https://cdn.jsdelivr.net/npm/vanilla-lazyload@16.0.0/dist/lazyload.min.js"></script> | ||
``` | ||
@@ -207,3 +207,3 @@ | ||
```js | ||
var lazyLoadAmdUrl = "https://cdn.jsdelivr.net/npm/vanilla-lazyload@15.2.0/dist/lazyload.amd.min.js"; | ||
var lazyLoadAmdUrl = "https://cdn.jsdelivr.net/npm/vanilla-lazyload@16.0.0/dist/lazyload.amd.min.js"; | ||
var polyfillAmdUrl = "https://cdn.jsdelivr.net/npm/intersection-observer-amd@2.0.1/intersection-observer-amd.js"; | ||
@@ -254,3 +254,3 @@ | ||
async | ||
src="https://cdn.jsdelivr.net/npm/vanilla-lazyload@15.2.0/dist/lazyload.min.js" | ||
src="https://cdn.jsdelivr.net/npm/vanilla-lazyload@16.0.0/dist/lazyload.min.js" | ||
></script> | ||
@@ -288,3 +288,3 @@ ``` | ||
async | ||
src="https://cdn.jsdelivr.net/npm/vanilla-lazyload@15.2.0/dist/lazyload.min.js" | ||
src="https://cdn.jsdelivr.net/npm/vanilla-lazyload@16.0.0/dist/lazyload.min.js" | ||
></script> | ||
@@ -518,5 +518,5 @@ ``` | ||
### Lazy LazyLoad | ||
### Lazy functions | ||
> 💡 **Use case**: when you have a lot of scrolling containers in the page and you want to instantiate a LazyLoad only on the ones that are in the viewport. | ||
> 💡 **Use case**: when you want to execute arbitrary scripts or functions when given elements enter the viewport | ||
@@ -526,2 +526,60 @@ HTML | ||
```html | ||
<div data-lazy-function="foo">...</div> | ||
<div data-lazy-function="bar">...</div> | ||
<div data-lazy-function="buzz">...</div> | ||
<div data-lazy-function="booya">...</div> | ||
``` | ||
JS | ||
```js | ||
// It's a best practice to scope the function names inside a namespace like `lazyFunctions`. | ||
window.lazyFunctions = { | ||
foo: function (element) { | ||
element.style.color = "red"; | ||
console.log("foo"); | ||
}, | ||
bar: function (element) { | ||
element.remove(element); | ||
console.log("bar"); | ||
}, | ||
buzz: function (element) { | ||
var span = document.createElement("span"); | ||
span.innerText = " - buzz!"; | ||
element.appendChild(span); | ||
console.log("buzz"); | ||
}, | ||
booya: function (element) { | ||
element.classList.add("boo"); | ||
console.log("booya"); | ||
} | ||
}; | ||
``` | ||
```js | ||
function executeLazyFunction(element) { | ||
var lazyFunctionName = element.getAttribute("data-lazy-function"); | ||
var lazyFunction = window.lazyFunctions[lazyFunctionName]; // window[lazyFunctionName] to call a global | ||
if (!lazyFunction) return; | ||
lazyFunction(element); | ||
} | ||
var ll = new LazyLoad({ | ||
elements_selector: "[data-lazy-function]", | ||
unobserve_entered: true, // <- Avoid executing the function multiple times | ||
callback_enter: executeLazyFunction // Assigning the function defined above | ||
}); | ||
``` | ||
That's it. Whenever an element with the `data-lazy-function` attribute enters the viewport, LazyLoad calls the `executeLazyScript` function, which gets the function name from the `data-lazy-function` attribute itself and executes it. | ||
[DEMO](https://verlok.github.io/lazyload/demos/lazy_functions.html) - [SOURCE](https://github.com/verlok/lazyload/blob/master/demos/lazy_functions.html) - [API](#-api) | ||
### Lazy initialization of multiple LazyLoad instances | ||
> 💡 **Use case**: when you have a lot of horizontally scrolling containers and you want to instantiate a LazyLoad instance on them, but only when they entered the viewport. | ||
HTML | ||
```html | ||
<div class="horzContainer"> | ||
@@ -559,20 +617,24 @@ <img | ||
var lazyLoadInstances = []; | ||
// The "lazyLazy" instance of lazyload is used (kinda improperly) | ||
// to check when the .horzContainer divs enter the viewport | ||
var initOneLazyLoad = function (horzContainerElement) { | ||
// When the .horzContainer element enters the viewport, | ||
// instantiate a new LazyLoad on the horzContainerElement | ||
var oneLL = new LazyLoad({ | ||
container: horzContainerElement | ||
}); | ||
// Optionally push it in the lazyLoadInstances | ||
// array to keep track of the instances | ||
lazyLoadInstances.push(oneLL); | ||
}; | ||
// The "lazyLazy" instance of lazyload is used to check | ||
// when the .horzContainer divs enter the viewport | ||
var lazyLazy = new LazyLoad({ | ||
elements_selector: ".horzContainer", | ||
// When the .horzContainer div enters the viewport... | ||
callback_enter: function (el) { | ||
// ...instantiate a new LazyLoad on it | ||
var oneLL = new LazyLoad({ | ||
container: el | ||
}); | ||
// Optionally push it in the lazyLoadInstances | ||
// array to keep track of the instances | ||
lazyLoadInstances.push(oneLL); | ||
} | ||
callback_enter: initOneLazyLoad, | ||
unobserve_entered: true // Stop observing .horzContainer(s) after they entered | ||
}); | ||
``` | ||
That's it. Whenever a `.horzContainer` element enters the viewport, LazyLoad calls the `callback_enter` function, which creates a new instance of LazyLoad on the `.horzContainer` element. | ||
That's it. Whenever a `.horzContainer` element enters the viewport, LazyLoad calls the `initOneLazyLoad` function, which creates a new instance of LazyLoad on the `.horzContainer` element. | ||
@@ -604,2 +666,3 @@ [DEMO](https://verlok.github.io/lazyload/demos/lazily_load_lazyLoad.html) - [SOURCE](https://github.com/verlok/lazyload/blob/master/demos/lazily_load_lazyLoad.html) - [API](#-api) | ||
| Content | Lazy loading background images | [Code](demos/background_images.html) | [Live](https://www.andreaverlicchi.eu/lazyload/demos/background_images.html) | | ||
| Content | Lazy loading multiple background images | [Code](demos/background_images_multi.html) | [Live](https://www.andreaverlicchi.eu/lazyload/demos/background_images_multi.html) | | ||
| Content | Lazy WebP images with the `<picture>` tag and the `type` attribute for WebP | [Code](demos/picture_type_webp.html) | [Live](https://www.andreaverlicchi.eu/lazyload/demos/picture_type_webp.html) | | ||
@@ -611,2 +674,3 @@ | Loading | Asynchronous loading LazyLoad with requireJS | [Code](demos/amd.html) | [Live](https://www.andreaverlicchi.eu/lazyload/demos/amd.html) | | ||
| Technique | Lazily create lazyload instances | [Code](demos/lazily_load_lazyLoad.html) | [Live](https://www.andreaverlicchi.eu/lazyload/demos/lazily_load_lazyLoad.html) | | ||
| Technique | Lazily execute functions as specific elements enter the viewport | [Code](demos/lazy_functions.html) | [Live](https://www.andreaverlicchi.eu/lazyload/demos/lazy_functions.html) | | ||
| Technique | How to manage the print of a page with lazy images | [Code](demos/print.html) | [Live](https://www.andreaverlicchi.eu/lazyload/demos/print.html) | | ||
@@ -616,3 +680,2 @@ | Technique | A popup layer containing lazy images in a scrolling container | [Code](demos/popup_layer.html) | [Live](https://www.andreaverlicchi.eu/lazyload/demos/popup_layer.html) | | ||
| Settings | Single scrolling container | [Code](demos/container_single.html) | [Live](https://www.andreaverlicchi.eu/lazyload/demos/container_single.html) | | ||
| Settings | Delay loading of lazy images | [Code](demos/delay.html) | [Live](https://www.andreaverlicchi.eu/lazyload/demos/delay.html) | | ||
| Settings | Cancel downloads on exit, optimizing for slow connections | [Code](demos/cancel_on_exit.html) | [Live](https://www.andreaverlicchi.eu/lazyload/demos/cancel_on_exit.html) | | ||
@@ -626,3 +689,2 @@ | Methods | How to `destroy()` LazyLoad | [Code](demos/destroy.html) | [Live](https://www.andreaverlicchi.eu/lazyload/demos/destroy.html) | | ||
| Test | Test behaviour with hidden images | [Code](demos/image_hidden.html) | [Live](https://www.andreaverlicchi.eu/lazyload/demos/image_hidden.html) | | ||
| Test | Test of delay loading | [Code](demos/delay_test.html) | [Live](https://www.andreaverlicchi.eu/lazyload/demos/delay_test.html) | | ||
| Test | Test performance, lazy loading of hundreds of images | [Code](demos/hundreds.html) | [Live](https://www.andreaverlicchi.eu/lazyload/demos/hundreds.html) | | ||
@@ -747,8 +809,7 @@ | Native | Test the native lazy loading of images _WITHOUT_ any line of javascript, not even this script | [Code](demos/native_lazyload.html) | [Live](https://www.andreaverlicchi.eu/lazyload/demos/native_lazyload.html) | | ||
| `cancel_on_exit` | A boolean that defines whether or not to cancel the download of the images that exit the viewport while they are still loading, eventually restoring the original attributes. It applies only to images so to the `img` (and `picture`) tags, so it doesn't apply to background images, `iframe`s nor `video`s. | `false` | `true` | | ||
| `load_delay` | The time (in milliseconds) each image needs to stay inside the viewport before its loading begins. | `0` | `300` | | ||
| `auto_unobserve` | A boolean that defines whether or not to automatically unobserve elements that was already revealed | `true` | `false` | | ||
| `unobserve_entered` | A boolean that defines whether or not to automatically unobserve elements once they entered the viewport | `true` | `false` | | ||
| `unobserve_completed` | A boolean that defines whether or not to automatically unobserve elements once they've loaded or throwed an error | `false` | `true` | | ||
| `callback_enter` | A callback function which is called whenever an element enters the viewport. Arguments: DOM element, intersection observer entry, lazyload instance. | `null` | `(el)=>{console.log("Entered", el)}` | | ||
| `callback_exit` | A callback function which is called whenever an element exits the viewport. Arguments: DOM element, intersection observer entry, lazyload instance. | `null` | `(el)=>{console.log("Exited", el)}` | | ||
| `callback_loading` | A callback function which is called whenever an element starts loading. Arguments: DOM element, lazyload instance. | `null` | `(el)=>{console.log("Loading", el)}` | | ||
| `callback_reveal` | **⚠ DEPRECATED: use `callback_loading` instead.** A callback function which is called whenever an element starts loading. Arguments: DOM element, lazyload instance. | `null` | `(el)=>{console.log("Loading", el)}` | | ||
| `callback_cancel` | A callback function which is called whenever an element loading is canceled while loading, as for `cancel_on_exit: true`. | `null` | `(el)=>{console.log("Cancelled", el)}` | | ||
@@ -767,9 +828,7 @@ | `callback_loaded` | A callback function which is called whenever an element finishes loading. Note that, in version older than 11.0.0, this option went under the name `callback_load`. Arguments: DOM element, lazyload instance. | `null` | `(el)=>{console.log("Loaded", el)}` | | ||
| Method name | Effect | Use case | | ||
| ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| `update()` | Make LazyLoad to re-check the DOM for `elements_selector` elements inside its `container`. | Update LazyLoad after you added or removed DOM elements to the page. | | ||
| `loadAll()` | Loads all the lazy images right away, no matter if they are inside or outside the viewport. | To load all the remaining elements in advance | | ||
| `load(element)` | **⚠ DEPRECATED, use the static method instead**. Immediately loads any lazy `element`, even if it isn't selectable by the `elements_selector` option. | To load an element at mouseover or any other event different than "entering the viewport" | | ||
| `destroy()` | Destroys the instance, unsetting instance variables and removing listeners. | Free up some memory. Especially useful for Single Page Applications. | | ||
| `resetElementStatus(element)` | Resets the internal status of the given `element`. | To tell LazyLoad to consider this `element` again, for example if you changed the `data-src` attribute after the previous `data-src` was loaded, call this method, then call `update()`. | | ||
| Method name | Effect | Use case | | ||
| ----------- | ------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- | | ||
| `update()` | Make LazyLoad to re-check the DOM for `elements_selector` elements inside its `container`. | Update LazyLoad after you added or removed DOM elements to the page. | | ||
| `loadAll()` | Loads all the lazy images right away, no matter if they are inside or outside the viewport. | To load all the remaining elements in advance | | ||
| `destroy()` | Destroys the instance, unsetting instance variables and removing listeners. | Free up some memory. Especially useful for Single Page Applications. | | ||
@@ -780,5 +839,6 @@ **Static methods** | ||
| Method name | Effect | Use case | | ||
| ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | | ||
| `load(element, settings)` | Immediately loads the lazy `element`. You can pass your custom options in the `settings` parameter. Note that the `elements_selector` option has no effect, since you are passing the element as a parameter. Also note that this method has effect only once on a specific `element`. | To load an `element` at mouseover or at any other event different than "entering the viewport" | | ||
| Method name | Effect | Use case | | ||
| ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| `load(element, settings)` | Immediately loads the lazy `element`. You can pass your custom options in the `settings` parameter. Note that the `elements_selector` option has no effect, since you are passing the element as a parameter. Also note that this method has effect only once on a specific `element`. | To load an `element` at mouseover or at any other event different than "entering the viewport" | | ||
| `resetStatus(element)` | Resets the internal status of the given `element`. | To tell LazyLoad to consider this `element` again, for example if you changed the `data-src` attribute after the previous `data-src` was loaded, call this method, then call `update()`. | | ||
@@ -785,0 +845,0 @@ ### Properties |
885
207195
2535