UNPKG

24.6 kBJavaScriptView Raw
1var LazyLoad = (function () {
2 'use strict';
3
4 const runningOnBrowser = typeof window !== "undefined";
5 const isBot = runningOnBrowser && !("onscroll" in window) || typeof navigator !== "undefined" && /(gle|ing|ro)bot|crawl|spider/i.test(navigator.userAgent);
6 const isHiDpi = runningOnBrowser && window.devicePixelRatio > 1;
7
8 const defaultSettings = {
9 elements_selector: ".lazy",
10 container: isBot || runningOnBrowser ? document : null,
11 threshold: 300,
12 thresholds: null,
13 data_src: "src",
14 data_srcset: "srcset",
15 data_sizes: "sizes",
16 data_bg: "bg",
17 data_bg_hidpi: "bg-hidpi",
18 data_bg_multi: "bg-multi",
19 data_bg_multi_hidpi: "bg-multi-hidpi",
20 data_bg_set: "bg-set",
21 data_poster: "poster",
22 class_applied: "applied",
23 class_loading: "loading",
24 class_loaded: "loaded",
25 class_error: "error",
26 class_entered: "entered",
27 class_exited: "exited",
28 unobserve_completed: true,
29 unobserve_entered: false,
30 cancel_on_exit: true,
31 callback_enter: null,
32 callback_exit: null,
33 callback_applied: null,
34 callback_loading: null,
35 callback_loaded: null,
36 callback_error: null,
37 callback_finish: null,
38 callback_cancel: null,
39 use_native: false,
40 restore_on_error: false
41 };
42 const getExtendedSettings = customSettings => {
43 return Object.assign({}, defaultSettings, customSettings);
44 };
45
46 /* Creates instance and notifies it through the window element */
47 const createInstance = function (classObj, options) {
48 let event;
49 const eventString = "LazyLoad::Initialized";
50 const instance = new classObj(options);
51 try {
52 // Works in modern browsers
53 event = new CustomEvent(eventString, {
54 detail: {
55 instance
56 }
57 });
58 } catch (err) {
59 // Works in Internet Explorer (all versions)
60 event = document.createEvent("CustomEvent");
61 event.initCustomEvent(eventString, false, false, {
62 instance
63 });
64 }
65 window.dispatchEvent(event);
66 };
67
68 /* Auto initialization of one or more instances of LazyLoad, depending on the
69 options passed in (plain object or an array) */
70 const autoInitialize = (classObj, options) => {
71 if (!options) {
72 return;
73 }
74 if (!options.length) {
75 // Plain object
76 createInstance(classObj, options);
77 } else {
78 // Array of objects
79 for (let i = 0, optionsItem; optionsItem = options[i]; i += 1) {
80 createInstance(classObj, optionsItem);
81 }
82 }
83 };
84
85 const SRC = "src";
86 const SRCSET = "srcset";
87 const SIZES = "sizes";
88 const POSTER = "poster";
89 const ORIGINALS = "llOriginalAttrs";
90 const DATA = "data";
91
92 const statusLoading = "loading";
93 const statusLoaded = "loaded";
94 const statusApplied = "applied";
95 const statusEntered = "entered";
96 const statusError = "error";
97 const statusNative = "native";
98
99 const dataPrefix = "data-";
100 const statusDataName = "ll-status";
101 const getData = (element, attribute) => {
102 return element.getAttribute(dataPrefix + attribute);
103 };
104 const setData = (element, attribute, value) => {
105 const attrName = dataPrefix + attribute;
106 if (value === null) {
107 element.removeAttribute(attrName);
108 return;
109 }
110 element.setAttribute(attrName, value);
111 };
112 const getStatus = element => getData(element, statusDataName);
113 const setStatus = (element, status) => setData(element, statusDataName, status);
114 const resetStatus = element => setStatus(element, null);
115 const hasEmptyStatus = element => getStatus(element) === null;
116 const hasStatusLoading = element => getStatus(element) === statusLoading;
117 const hasStatusError = element => getStatus(element) === statusError;
118 const hasStatusNative = element => getStatus(element) === statusNative;
119 const statusesAfterLoading = [statusLoading, statusLoaded, statusApplied, statusError];
120 const hadStartedLoading = element => statusesAfterLoading.indexOf(getStatus(element)) >= 0;
121
122 const safeCallback = (callback, arg1, arg2, arg3) => {
123 if (!callback || typeof callback !== 'function') {
124 return;
125 }
126 if (arg3 !== undefined) {
127 callback(arg1, arg2, arg3);
128 return;
129 }
130 if (arg2 !== undefined) {
131 callback(arg1, arg2);
132 return;
133 }
134 callback(arg1);
135 };
136
137 const addClass = (element, className) => {
138 if (!runningOnBrowser) {
139 return;
140 }
141 if (className === "") {
142 return;
143 }
144 element.classList.add(className);
145 };
146 const removeClass = (element, className) => {
147 if (!runningOnBrowser) {
148 return;
149 }
150 if (className === "") {
151 return;
152 }
153 element.classList.remove(className);
154 };
155
156 const addTempImage = element => {
157 element.llTempImage = document.createElement("IMG");
158 };
159 const deleteTempImage = element => {
160 delete element.llTempImage;
161 };
162 const getTempImage = element => element.llTempImage;
163
164 const unobserve = (element, instance) => {
165 if (!instance) return;
166 const observer = instance._observer;
167 if (!observer) return;
168 observer.unobserve(element);
169 };
170 const resetObserver = observer => {
171 observer.disconnect();
172 };
173 const unobserveEntered = (element, settings, instance) => {
174 if (settings.unobserve_entered) unobserve(element, instance);
175 };
176
177 const updateLoadingCount = (instance, delta) => {
178 if (!instance) return;
179 instance.loadingCount += delta;
180 };
181 const decreaseToLoadCount = instance => {
182 if (!instance) return;
183 instance.toLoadCount -= 1;
184 };
185 const setToLoadCount = (instance, value) => {
186 if (!instance) return;
187 instance.toLoadCount = value;
188 };
189 const isSomethingLoading = instance => instance.loadingCount > 0;
190 const haveElementsToLoad = instance => instance.toLoadCount > 0;
191
192 const getSourceTags = parentTag => {
193 let sourceTags = [];
194 for (let i = 0, childTag; childTag = parentTag.children[i]; i += 1) {
195 if (childTag.tagName === "SOURCE") {
196 sourceTags.push(childTag);
197 }
198 }
199 return sourceTags;
200 };
201 const forEachPictureSource = (element, fn) => {
202 const parent = element.parentNode;
203 if (!parent || parent.tagName !== "PICTURE") {
204 return;
205 }
206 let sourceTags = getSourceTags(parent);
207 sourceTags.forEach(fn);
208 };
209 const forEachVideoSource = (element, fn) => {
210 let sourceTags = getSourceTags(element);
211 sourceTags.forEach(fn);
212 };
213
214 const attrsSrc = [SRC];
215 const attrsSrcPoster = [SRC, POSTER];
216 const attrsSrcSrcsetSizes = [SRC, SRCSET, SIZES];
217 const attrsData = [DATA];
218 const hasOriginalAttrs = element => !!element[ORIGINALS];
219 const getOriginalAttrs = element => element[ORIGINALS];
220 const deleteOriginalAttrs = element => delete element[ORIGINALS];
221
222 // ## SAVE ##
223
224 const setOriginalsObject = (element, attributes) => {
225 if (hasOriginalAttrs(element)) {
226 return;
227 }
228 const originals = {};
229 attributes.forEach(attribute => {
230 originals[attribute] = element.getAttribute(attribute);
231 });
232 element[ORIGINALS] = originals;
233 };
234 const saveOriginalBackgroundStyle = element => {
235 if (hasOriginalAttrs(element)) {
236 return;
237 }
238 element[ORIGINALS] = {
239 backgroundImage: element.style.backgroundImage
240 };
241 };
242
243 // ## RESTORE ##
244
245 const setOrResetAttribute = (element, attrName, value) => {
246 if (!value) {
247 element.removeAttribute(attrName);
248 return;
249 }
250 element.setAttribute(attrName, value);
251 };
252 const restoreOriginalAttrs = (element, attributes) => {
253 if (!hasOriginalAttrs(element)) {
254 return;
255 }
256 const originals = getOriginalAttrs(element);
257 attributes.forEach(attribute => {
258 setOrResetAttribute(element, attribute, originals[attribute]);
259 });
260 };
261 const restoreOriginalBgImage = element => {
262 if (!hasOriginalAttrs(element)) {
263 return;
264 }
265 const originals = getOriginalAttrs(element);
266 element.style.backgroundImage = originals.backgroundImage;
267 };
268
269 const manageApplied = (element, settings, instance) => {
270 addClass(element, settings.class_applied);
271 setStatus(element, statusApplied);
272 // Instance is not provided when loading is called from static class
273 if (!instance) return;
274 if (settings.unobserve_completed) {
275 // Unobserve now because we can't do it on load
276 unobserve(element, settings);
277 }
278 safeCallback(settings.callback_applied, element, instance);
279 };
280 const manageLoading = (element, settings, instance) => {
281 addClass(element, settings.class_loading);
282 setStatus(element, statusLoading);
283 // Instance is not provided when loading is called from static class
284 if (!instance) return;
285 updateLoadingCount(instance, +1);
286 safeCallback(settings.callback_loading, element, instance);
287 };
288 const setAttributeIfValue = (element, attrName, value) => {
289 if (!value) {
290 return;
291 }
292 element.setAttribute(attrName, value);
293 };
294 const setImageAttributes = (element, settings) => {
295 setAttributeIfValue(element, SIZES, getData(element, settings.data_sizes));
296 setAttributeIfValue(element, SRCSET, getData(element, settings.data_srcset));
297 setAttributeIfValue(element, SRC, getData(element, settings.data_src));
298 };
299 const setSourcesImg = (imgEl, settings) => {
300 forEachPictureSource(imgEl, sourceTag => {
301 setOriginalsObject(sourceTag, attrsSrcSrcsetSizes);
302 setImageAttributes(sourceTag, settings);
303 });
304 setOriginalsObject(imgEl, attrsSrcSrcsetSizes);
305 setImageAttributes(imgEl, settings);
306 };
307 const setSourcesIframe = (iframe, settings) => {
308 setOriginalsObject(iframe, attrsSrc);
309 setAttributeIfValue(iframe, SRC, getData(iframe, settings.data_src));
310 };
311 const setSourcesVideo = (videoEl, settings) => {
312 forEachVideoSource(videoEl, sourceEl => {
313 setOriginalsObject(sourceEl, attrsSrc);
314 setAttributeIfValue(sourceEl, SRC, getData(sourceEl, settings.data_src));
315 });
316 setOriginalsObject(videoEl, attrsSrcPoster);
317 setAttributeIfValue(videoEl, POSTER, getData(videoEl, settings.data_poster));
318 setAttributeIfValue(videoEl, SRC, getData(videoEl, settings.data_src));
319 videoEl.load();
320 };
321 const setSourcesObject = (object, settings) => {
322 setOriginalsObject(object, attrsData);
323 setAttributeIfValue(object, DATA, getData(object, settings.data_src));
324 };
325 const setBackground = (element, settings, instance) => {
326 const bg1xValue = getData(element, settings.data_bg);
327 const bgHiDpiValue = getData(element, settings.data_bg_hidpi);
328 const bgDataValue = isHiDpi && bgHiDpiValue ? bgHiDpiValue : bg1xValue;
329 if (!bgDataValue) return;
330 element.style.backgroundImage = `url("${bgDataValue}")`;
331 getTempImage(element).setAttribute(SRC, bgDataValue);
332 manageLoading(element, settings, instance);
333 };
334
335 // NOTE: THE TEMP IMAGE TRICK CANNOT BE DONE WITH data-multi-bg
336 // BECAUSE INSIDE ITS VALUES MUST BE WRAPPED WITH URL() AND ONE OF THEM
337 // COULD BE A GRADIENT BACKGROUND IMAGE
338 const setMultiBackground = (element, settings, instance) => {
339 const bg1xValue = getData(element, settings.data_bg_multi);
340 const bgHiDpiValue = getData(element, settings.data_bg_multi_hidpi);
341 const bgDataValue = isHiDpi && bgHiDpiValue ? bgHiDpiValue : bg1xValue;
342 if (!bgDataValue) {
343 return;
344 }
345 element.style.backgroundImage = bgDataValue;
346 manageApplied(element, settings, instance);
347 };
348 const setImgsetBackground = (element, settings, instance) => {
349 const bgImgSetDataValue = getData(element, settings.data_bg_set);
350 if (!bgImgSetDataValue) {
351 return;
352 }
353 const imgSetValues = bgImgSetDataValue.split("|");
354 let bgImageValues = imgSetValues.map(value => `image-set(${value})`);
355 element.style.backgroundImage = bgImageValues.join();
356 manageApplied(element, settings, instance);
357 };
358 const setSourcesFunctions = {
359 IMG: setSourcesImg,
360 IFRAME: setSourcesIframe,
361 VIDEO: setSourcesVideo,
362 OBJECT: setSourcesObject
363 };
364 const setSourcesNative = (element, settings) => {
365 const setSourcesFunction = setSourcesFunctions[element.tagName];
366 if (!setSourcesFunction) {
367 return;
368 }
369 setSourcesFunction(element, settings);
370 };
371 const setSources = (element, settings, instance) => {
372 const setSourcesFunction = setSourcesFunctions[element.tagName];
373 if (!setSourcesFunction) {
374 return;
375 }
376 setSourcesFunction(element, settings);
377 manageLoading(element, settings, instance);
378 };
379
380 const elementsWithLoadEvent = ["IMG", "IFRAME", "VIDEO", "OBJECT"];
381 const hasLoadEvent = element => elementsWithLoadEvent.indexOf(element.tagName) > -1;
382 const checkFinish = (settings, instance) => {
383 if (instance && !isSomethingLoading(instance) && !haveElementsToLoad(instance)) {
384 safeCallback(settings.callback_finish, instance);
385 }
386 };
387 const addEventListener = (element, eventName, handler) => {
388 element.addEventListener(eventName, handler);
389 element.llEvLisnrs[eventName] = handler;
390 };
391 const removeEventListener = (element, eventName, handler) => {
392 element.removeEventListener(eventName, handler);
393 };
394 const hasEventListeners = element => {
395 return !!element.llEvLisnrs;
396 };
397 const addEventListeners = (element, loadHandler, errorHandler) => {
398 if (!hasEventListeners(element)) element.llEvLisnrs = {};
399 const loadEventName = element.tagName === "VIDEO" ? "loadeddata" : "load";
400 addEventListener(element, loadEventName, loadHandler);
401 addEventListener(element, "error", errorHandler);
402 };
403 const removeEventListeners = element => {
404 if (!hasEventListeners(element)) {
405 return;
406 }
407 const eventListeners = element.llEvLisnrs;
408 for (let eventName in eventListeners) {
409 const handler = eventListeners[eventName];
410 removeEventListener(element, eventName, handler);
411 }
412 delete element.llEvLisnrs;
413 };
414 const doneHandler = (element, settings, instance) => {
415 deleteTempImage(element);
416 updateLoadingCount(instance, -1);
417 decreaseToLoadCount(instance);
418 removeClass(element, settings.class_loading);
419 if (settings.unobserve_completed) {
420 unobserve(element, instance);
421 }
422 };
423 const loadHandler = (event, element, settings, instance) => {
424 const goingNative = hasStatusNative(element);
425 doneHandler(element, settings, instance);
426 addClass(element, settings.class_loaded);
427 setStatus(element, statusLoaded);
428 safeCallback(settings.callback_loaded, element, instance);
429 if (!goingNative) checkFinish(settings, instance);
430 };
431 const errorHandler = (event, element, settings, instance) => {
432 const goingNative = hasStatusNative(element);
433 doneHandler(element, settings, instance);
434 addClass(element, settings.class_error);
435 setStatus(element, statusError);
436 safeCallback(settings.callback_error, element, instance);
437 if (settings.restore_on_error) restoreOriginalAttrs(element, attrsSrcSrcsetSizes);
438 if (!goingNative) checkFinish(settings, instance);
439 };
440 const addOneShotEventListeners = (element, settings, instance) => {
441 const elementToListenTo = getTempImage(element) || element;
442 if (hasEventListeners(elementToListenTo)) {
443 // This happens when loading is retried twice
444 return;
445 }
446 const _loadHandler = event => {
447 loadHandler(event, element, settings, instance);
448 removeEventListeners(elementToListenTo);
449 };
450 const _errorHandler = event => {
451 errorHandler(event, element, settings, instance);
452 removeEventListeners(elementToListenTo);
453 };
454 addEventListeners(elementToListenTo, _loadHandler, _errorHandler);
455 };
456
457 const loadBackground = (element, settings, instance) => {
458 addTempImage(element);
459 addOneShotEventListeners(element, settings, instance);
460 saveOriginalBackgroundStyle(element);
461 setBackground(element, settings, instance);
462 setMultiBackground(element, settings, instance);
463 setImgsetBackground(element, settings, instance);
464 };
465 const loadRegular = (element, settings, instance) => {
466 addOneShotEventListeners(element, settings, instance);
467 setSources(element, settings, instance);
468 };
469 const load = (element, settings, instance) => {
470 if (hasLoadEvent(element)) {
471 loadRegular(element, settings, instance);
472 } else {
473 loadBackground(element, settings, instance);
474 }
475 };
476 const loadNative = (element, settings, instance) => {
477 element.setAttribute("loading", "lazy");
478 addOneShotEventListeners(element, settings, instance);
479 setSourcesNative(element, settings);
480 setStatus(element, statusNative);
481 };
482
483 const removeImageAttributes = element => {
484 element.removeAttribute(SRC);
485 element.removeAttribute(SRCSET);
486 element.removeAttribute(SIZES);
487 };
488 const resetSourcesImg = element => {
489 forEachPictureSource(element, sourceTag => {
490 removeImageAttributes(sourceTag);
491 });
492 removeImageAttributes(element);
493 };
494
495 const restoreImg = imgEl => {
496 forEachPictureSource(imgEl, sourceEl => {
497 restoreOriginalAttrs(sourceEl, attrsSrcSrcsetSizes);
498 });
499 restoreOriginalAttrs(imgEl, attrsSrcSrcsetSizes);
500 };
501 const restoreVideo = videoEl => {
502 forEachVideoSource(videoEl, sourceEl => {
503 restoreOriginalAttrs(sourceEl, attrsSrc);
504 });
505 restoreOriginalAttrs(videoEl, attrsSrcPoster);
506 videoEl.load();
507 };
508 const restoreIframe = iframeEl => {
509 restoreOriginalAttrs(iframeEl, attrsSrc);
510 };
511 const restoreObject = objectEl => {
512 restoreOriginalAttrs(objectEl, attrsData);
513 };
514 const restoreFunctions = {
515 IMG: restoreImg,
516 IFRAME: restoreIframe,
517 VIDEO: restoreVideo,
518 OBJECT: restoreObject
519 };
520 const restoreAttributes = element => {
521 const restoreFunction = restoreFunctions[element.tagName];
522 if (!restoreFunction) {
523 restoreOriginalBgImage(element);
524 return;
525 }
526 restoreFunction(element);
527 };
528 const resetClasses = (element, settings) => {
529 if (hasEmptyStatus(element) || hasStatusNative(element)) {
530 return;
531 }
532 removeClass(element, settings.class_entered);
533 removeClass(element, settings.class_exited);
534 removeClass(element, settings.class_applied);
535 removeClass(element, settings.class_loading);
536 removeClass(element, settings.class_loaded);
537 removeClass(element, settings.class_error);
538 };
539 const restore = (element, settings) => {
540 restoreAttributes(element);
541 resetClasses(element, settings);
542 resetStatus(element);
543 deleteOriginalAttrs(element);
544 };
545
546 const cancelLoading = (element, entry, settings, instance) => {
547 if (!settings.cancel_on_exit) return;
548 if (!hasStatusLoading(element)) return;
549 if (element.tagName !== "IMG") return; //Works only on images
550 removeEventListeners(element);
551 resetSourcesImg(element);
552 restoreImg(element);
553 removeClass(element, settings.class_loading);
554 updateLoadingCount(instance, -1);
555 resetStatus(element);
556 safeCallback(settings.callback_cancel, element, entry, instance);
557 };
558
559 const onEnter = (element, entry, settings, instance) => {
560 const dontLoad = hadStartedLoading(element); /* Save status
561 before setting it, to prevent loading it again. Fixes #526. */
562 setStatus(element, statusEntered);
563 addClass(element, settings.class_entered);
564 removeClass(element, settings.class_exited);
565 unobserveEntered(element, settings, instance);
566 safeCallback(settings.callback_enter, element, entry, instance);
567 if (dontLoad) return;
568 load(element, settings, instance);
569 };
570 const onExit = (element, entry, settings, instance) => {
571 if (hasEmptyStatus(element)) return; //Ignore the first pass, at landing
572 addClass(element, settings.class_exited);
573 cancelLoading(element, entry, settings, instance);
574 safeCallback(settings.callback_exit, element, entry, instance);
575 };
576
577 const tagsWithNativeLazy = ["IMG", "IFRAME", "VIDEO"];
578 const shouldUseNative = settings => settings.use_native && "loading" in HTMLImageElement.prototype;
579 const loadAllNative = (elements, settings, instance) => {
580 elements.forEach(element => {
581 if (tagsWithNativeLazy.indexOf(element.tagName) === -1) {
582 return;
583 }
584 loadNative(element, settings, instance);
585 });
586 setToLoadCount(instance, 0);
587 };
588
589 const isIntersecting = entry => entry.isIntersecting || entry.intersectionRatio > 0;
590 const getObserverSettings = settings => ({
591 root: settings.container === document ? null : settings.container,
592 rootMargin: settings.thresholds || settings.threshold + "px"
593 });
594 const intersectionHandler = (entries, settings, instance) => {
595 entries.forEach(entry => isIntersecting(entry) ? onEnter(entry.target, entry, settings, instance) : onExit(entry.target, entry, settings, instance));
596 };
597 const observeElements = (observer, elements) => {
598 elements.forEach(element => {
599 observer.observe(element);
600 });
601 };
602 const updateObserver = (observer, elementsToObserve) => {
603 resetObserver(observer);
604 observeElements(observer, elementsToObserve);
605 };
606 const setObserver = (settings, instance) => {
607 if (shouldUseNative(settings)) {
608 return;
609 }
610 instance._observer = new IntersectionObserver(entries => {
611 intersectionHandler(entries, settings, instance);
612 }, getObserverSettings(settings));
613 };
614
615 const toArray = nodeSet => Array.prototype.slice.call(nodeSet);
616 const queryElements = settings => settings.container.querySelectorAll(settings.elements_selector);
617 const excludeManagedElements = elements => toArray(elements).filter(hasEmptyStatus);
618 const hasError = element => hasStatusError(element);
619 const filterErrorElements = elements => toArray(elements).filter(hasError);
620 const getElementsToLoad = (elements, settings) => excludeManagedElements(elements || queryElements(settings));
621
622 const retryLazyLoad = (settings, instance) => {
623 const errorElements = filterErrorElements(queryElements(settings));
624 errorElements.forEach(element => {
625 removeClass(element, settings.class_error);
626 resetStatus(element);
627 });
628 instance.update();
629 };
630 const setOnlineCheck = (settings, instance) => {
631 if (!runningOnBrowser) {
632 return;
633 }
634 instance._onlineHandler = () => {
635 retryLazyLoad(settings, instance);
636 };
637 window.addEventListener("online", instance._onlineHandler);
638 };
639 const resetOnlineCheck = instance => {
640 if (!runningOnBrowser) {
641 return;
642 }
643 window.removeEventListener("online", instance._onlineHandler);
644 };
645
646 const LazyLoad = function (customSettings, elements) {
647 const settings = getExtendedSettings(customSettings);
648 this._settings = settings;
649 this.loadingCount = 0;
650 setObserver(settings, this);
651 setOnlineCheck(settings, this);
652 this.update(elements);
653 };
654 LazyLoad.prototype = {
655 update: function (givenNodeset) {
656 const settings = this._settings;
657 const elementsToLoad = getElementsToLoad(givenNodeset, settings);
658 setToLoadCount(this, elementsToLoad.length);
659 if (isBot) {
660 this.loadAll(elementsToLoad);
661 return;
662 }
663 if (shouldUseNative(settings)) {
664 loadAllNative(elementsToLoad, settings, this);
665 return;
666 }
667 updateObserver(this._observer, elementsToLoad);
668 },
669 destroy: function () {
670 // Observer
671 if (this._observer) {
672 this._observer.disconnect();
673 }
674 // Clean handlers
675 resetOnlineCheck(this);
676 // Clean custom attributes on elements
677 queryElements(this._settings).forEach(element => {
678 deleteOriginalAttrs(element);
679 });
680 // Delete all internal props
681 delete this._observer;
682 delete this._settings;
683 delete this._onlineHandler;
684 delete this.loadingCount;
685 delete this.toLoadCount;
686 },
687 loadAll: function (elements) {
688 const settings = this._settings;
689 const elementsToLoad = getElementsToLoad(elements, settings);
690 elementsToLoad.forEach(element => {
691 unobserve(element, this);
692 load(element, settings, this);
693 });
694 },
695 restoreAll: function () {
696 const settings = this._settings;
697 queryElements(settings).forEach(element => {
698 restore(element, settings);
699 });
700 }
701 };
702 LazyLoad.load = (element, customSettings) => {
703 const settings = getExtendedSettings(customSettings);
704 load(element, settings);
705 };
706 LazyLoad.resetStatus = element => {
707 resetStatus(element);
708 };
709
710 // Automatic instances creation if required (useful for async script loading)
711 if (runningOnBrowser) {
712 autoInitialize(LazyLoad, window.lazyLoadOptions);
713 }
714
715 return LazyLoad;
716
717})();