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