1function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } 2 3function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } 4 5(function (global, factory) { 6 (typeof exports === "undefined" ? "undefined" : _typeof(exports)) === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : global.LazyLoad = factory(); 7})(this, function () { 8 'use strict'; 9 10 var runningOnBrowser = typeof window !== "undefined"; 11 var isBot = runningOnBrowser && !("onscroll" in window) || typeof navigator !== "undefined" && /(gle|ing|ro)bot|crawl|spider/i.test(navigator.userAgent); 12 var supportsIntersectionObserver = runningOnBrowser && "IntersectionObserver" in window; 13 var supportsClassList = runningOnBrowser && "classList" in document.createElement("p"); 14 var defaultSettings = { 15 elements_selector: "img", 16 container: isBot || runningOnBrowser ? document : null, 17 threshold: 300, 18 thresholds: null, 19 data_src: "src", 20 data_srcset: "srcset", 21 data_sizes: "sizes", 22 data_bg: "bg", 23 class_loading: "loading", 24 class_loaded: "loaded", 25 class_error: "error", 26 load_delay: 0, 27 auto_unobserve: true, 28 callback_enter: null, 29 callback_exit: null, 30 callback_reveal: null, 31 callback_loaded: null, 32 callback_error: null, 33 callback_finish: null, 34 use_native: false 35 }; 36 37 var getInstanceSettings = function getInstanceSettings(customSettings) { 38 return _extends({}, defaultSettings, customSettings); 39 }; 40 /* Creates instance and notifies it through the window element */ 41 42 43 var createInstance = function createInstance(classObj, options) { 44 var event; 45 var eventString = "LazyLoad::Initialized"; 46 var instance = new classObj(options); 47 48 try { 49 // Works in modern browsers 50 event = new CustomEvent(eventString, { 51 detail: { 52 instance: instance 53 } 54 }); 55 } catch (err) { 56 // Works in Internet Explorer (all versions) 57 event = document.createEvent("CustomEvent"); 58 event.initCustomEvent(eventString, false, false, { 59 instance: instance 60 }); 61 } 62 63 window.dispatchEvent(event); 64 }; 65 /* Auto initialization of one or more instances of lazyload, depending on the 66 options passed in (plain object or an array) */ 67 68 69 function autoInitialize(classObj, options) { 70 if (!options) { 71 return; 72 } 73 74 if (!options.length) { 75 // Plain object 76 createInstance(classObj, options); 77 } else { 78 // Array of objects 79 for (var i = 0, optionsItem; optionsItem = options[i]; i += 1) { 80 createInstance(classObj, optionsItem); 81 } 82 } 83 } 84 85 var dataPrefix = "data-"; 86 var processedDataName = "was-processed"; 87 var timeoutDataName = "ll-timeout"; 88 var trueString = "true"; 89 90 var getData = function getData(element, attribute) { 91 return element.getAttribute(dataPrefix + attribute); 92 }; 93 94 var setData = function setData(element, attribute, value) { 95 var attrName = dataPrefix + attribute; 96 97 if (value === null) { 98 element.removeAttribute(attrName); 99 return; 100 } 101 102 element.setAttribute(attrName, value); 103 }; 104 105 var setWasProcessedData = function setWasProcessedData(element) { 106 return setData(element, processedDataName, trueString); 107 }; 108 109 var getWasProcessedData = function getWasProcessedData(element) { 110 return getData(element, processedDataName) === trueString; 111 }; 112 113 var setTimeoutData = function setTimeoutData(element, value) { 114 return setData(element, timeoutDataName, value); 115 }; 116 117 var getTimeoutData = function getTimeoutData(element) { 118 return getData(element, timeoutDataName); 119 }; 120 121 var purgeProcessedElements = function purgeProcessedElements(elements) { 122 return elements.filter(function (element) { 123 return !getWasProcessedData(element); 124 }); 125 }; 126 127 var purgeOneElement = function purgeOneElement(elements, elementToPurge) { 128 return elements.filter(function (element) { 129 return element !== elementToPurge; 130 }); 131 }; 132 133 var callbackIfSet = function callbackIfSet(callback, argument) { 134 if (callback) { 135 callback(argument); 136 } 137 }; 138 139 var updateLoadingCount = function updateLoadingCount(instance, plusMinus) { 140 instance._loadingCount += plusMinus; 141 142 if (instance._elements.length === 0 && instance._loadingCount === 0) { 143 callbackIfSet(instance._settings.callback_finish); 144 } 145 }; 146 147 var getSourceTags = function getSourceTags(parentTag) { 148 var sourceTags = []; 149 150 for (var i = 0, childTag; childTag = parentTag.children[i]; i += 1) { 151 if (childTag.tagName === "SOURCE") { 152 sourceTags.push(childTag); 153 } 154 } 155 156 return sourceTags; 157 }; 158 159 var setAttributeIfValue = function setAttributeIfValue(element, attrName, value) { 160 if (!value) { 161 return; 162 } 163 164 element.setAttribute(attrName, value); 165 }; 166 167 var setImageAttributes = function setImageAttributes(element, settings) { 168 setAttributeIfValue(element, "sizes", getData(element, settings.data_sizes)); 169 setAttributeIfValue(element, "srcset", getData(element, settings.data_srcset)); 170 setAttributeIfValue(element, "src", getData(element, settings.data_src)); 171 }; 172 173 var setSourcesImg = function setSourcesImg(element, settings) { 174 var parent = element.parentNode; 175 176 if (parent && parent.tagName === "PICTURE") { 177 var sourceTags = getSourceTags(parent);
178 sourceTags.forEach(function (sourceTag) { 179 setImageAttributes(sourceTag, settings); 180 }); 181 } 182 183 setImageAttributes(element, settings); 184 }; 185 186 var setSourcesIframe = function setSourcesIframe(element, settings) { 187 setAttributeIfValue(element, "src", getData(element, settings.data_src)); 188 }; 189 190 var setSourcesVideo = function setSourcesVideo(element, settings) { 191 var sourceTags = getSourceTags(element); 192 sourceTags.forEach(function (sourceTag) { 193 setAttributeIfValue(sourceTag, "src", getData(sourceTag, settings.data_src)); 194 }); 195 setAttributeIfValue(element, "src", getData(element, settings.data_src)); 196 element.load(); 197 }; 198 199 var setSourcesBgImage = function setSourcesBgImage(element, settings) { 200 var srcDataValue = getData(element, settings.data_src); 201 var bgDataValue = getData(element, settings.data_bg); 202 203 if (srcDataValue) { 204 element.style.backgroundImage = "url(\"".concat(srcDataValue, "\")"); 205 } 206 207 if (bgDataValue) { 208 element.style.backgroundImage = bgDataValue; 209 } 210 }; 211 212 var setSourcesFunctions = { 213 IMG: setSourcesImg, 214 IFRAME: setSourcesIframe, 215 VIDEO: setSourcesVideo 216 }; 217 218 var setSources = function setSources(element, instance) { 219 var settings = instance._settings; 220 var tagName = element.tagName; 221 var setSourcesFunction = setSourcesFunctions[tagName]; 222 223 if (setSourcesFunction) { 224 setSourcesFunction(element, settings); 225 updateLoadingCount(instance, 1); 226 instance._elements = purgeOneElement(instance._elements, element); 227 return; 228 } 229 230 setSourcesBgImage(element, settings); 231 }; 232 233 var addClass = function addClass(element, className) { 234 if (supportsClassList) { 235 element.classList.add(className); 236 return; 237 } 238 239 element.className += (element.className ? " " : "") + className; 240 }; 241 242 var removeClass = function removeClass(element, className) { 243 if (supportsClassList) { 244 element.classList.remove(className); 245 return; 246 } 247 248 element.className = element.className.replace(new RegExp("(^|\\s+)" + className + "(\\s+|$)"), " ").replace(/^\s+/, "").replace(/\s+$/, ""); 249 }; 250 251 var genericLoadEventName = "load"; 252 var mediaLoadEventName = "loadeddata"; 253 var errorEventName = "error"; 254 255 var addEventListener = function addEventListener(element, eventName, handler) { 256 element.addEventListener(eventName, handler); 257 }; 258 259 var removeEventListener = function removeEventListener(element, eventName, handler) { 260 element.removeEventListener(eventName, handler); 261 }; 262 263 var addEventListeners = function addEventListeners(element, loadHandler, errorHandler) { 264 addEventListener(element, genericLoadEventName, loadHandler); 265 addEventListener(element, mediaLoadEventName, loadHandler); 266 addEventListener(element, errorEventName, errorHandler); 267 }; 268 269 var removeEventListeners = function removeEventListeners(element, loadHandler, errorHandler) { 270 removeEventListener(element, genericLoadEventName, loadHandler); 271 removeEventListener(element, mediaLoadEventName, loadHandler); 272 removeEventListener(element, errorEventName, errorHandler); 273 }; 274 275 var eventHandler = function eventHandler(event, success, instance) { 276 var settings = instance._settings; 277 var className = success ? settings.class_loaded : settings.class_error; 278 var callback = success ? settings.callback_loaded : settings.callback_error; 279 var element = event.target; 280 removeClass(element, settings.class_loading); 281 addClass(element, className); 282 callbackIfSet(callback, element); 283 updateLoadingCount(instance, -1); 284 }; 285 286 var addOneShotEventListeners = function addOneShotEventListeners(element, instance) { 287 var loadHandler = function loadHandler(event) { 288 eventHandler(event, true, instance); 289 removeEventListeners(element, loadHandler, errorHandler); 290 }; 291 292 var errorHandler = function errorHandler(event) { 293 eventHandler(event, false, instance); 294 removeEventListeners(element, loadHandler, errorHandler); 295 }; 296 297 addEventListeners(element, loadHandler, errorHandler); 298 }; 299 300 var managedTags = ["IMG", "IFRAME", "VIDEO"]; 301 302 var onEnter = function onEnter(element, instance) { 303 var settings = instance._settings; 304 callbackIfSet(settings.callback_enter, element); 305 306 if (!settings.load_delay) { 307 revealAndUnobserve(element, instance); 308 return; 309 } 310 311 delayLoad(element, instance); 312 }; 313 314 var revealAndUnobserve = function revealAndUnobserve(element, instance) { 315 var observer = instance._observer; 316 revealElement(element, instance); 317 318 if (observer && instance._settings.auto_unobserve) { 319 observer.unobserve(element); 320 } 321 }; 322 323 var onExit = function onExit(element, instance) { 324 var settings = instance._settings; 325 callbackIfSet(settings.callback_exit, element); 326 327 if (!settings.load_delay) { 328 return; 329 } 330 331 cancelDelayLoad(element); 332 }; 333 334 var cancelDelayLoad = function cancelDelayLoad(element) { 335 var timeoutId = getTimeoutData(element); 336 337 if (!timeoutId) { 338 return; // do nothing if timeout doesn't exist 339 } 340 341 clearTimeout(timeoutId); 342 setTimeoutData(element, null); 343 }; 344 345 var delayLoad = function delayLoad(element, instance) { 346 var loadDelay = instance._settings.load_delay; 347 var timeoutId = getTimeoutData(element); 348 349 if (timeoutId) { 350 return; // do nothing if timeout already set 351 } 352 353 timeoutId = setTimeout(function () { 354 revealAndUnobserve(element, instance); 355 cancelDelayLoad(element); 356 }, loadDelay); 357 setTimeoutData(element, timeoutId); 358 }; 359 360 var revealElement = function revealElement(element, instance, force) { 361 var settings = instance._settings; 362 363 if (!force && getWasProcessedData(element)) { 364 return; // element has already been processed and force wasn't true 365 } 366 367 if (managedTags.indexOf(element.tagName) > -1) { 368 addOneShotEventListeners(element, instance); 369 addClass(element, settings.class_loading); 370 } 371 372 setSources(element, instance); 373 setWasProcessedData(element); 374 callbackIfSet(settings.callback_reveal, element); 375 callbackIfSet(settings.callback_set, element); 376 }; 377 378 var isIntersecting = function isIntersecting(entry) { 379 return entry.isIntersecting || entry.intersectionRatio > 0; 380 }; 381 382 var getObserverSettings = function getObserverSettings(settings) { 383 return { 384 root: settings.container === document ? null : settings.container, 385 rootMargin: settings.thresholds || settings.threshold + "px" 386 }; 387 }; 388 389 var setObserver = function setObserver(instance) { 390 if (!supportsIntersectionObserver) { 391 return false;
392 } 393 394 instance._observer = new IntersectionObserver(function (entries) { 395 entries.forEach(function (entry) { 396 return isIntersecting(entry) ? onEnter(entry.target, instance) : onExit(entry.target, instance); 397 }); 398 }, getObserverSettings(instance._settings)); 399 return true; 400 }; 401 402 var nativeLazyTags = ["IMG", "IFRAME"]; 403 404 var shouldUseNative = function shouldUseNative(settings) { 405 return settings.use_native && "loading" in HTMLImageElement.prototype; 406 }; 407 408 var loadAllNative = function loadAllNative(instance) { 409 instance._elements.forEach(function (element) { 410 if (nativeLazyTags.indexOf(element.tagName) === -1) { 411 return; 412 } 413 414 element.setAttribute("loading", "lazy"); 415 revealElement(element, instance); 416 }); 417 }; 418 419 var nodeSetToArray = function nodeSetToArray(nodeSet) { 420 return Array.prototype.slice.call(nodeSet); 421 }; 422 423 var queryElements = function queryElements(settings) { 424 return settings.container.querySelectorAll(settings.elements_selector); 425 }; 426 427 var getElements = function getElements(elements, settings) { 428 return purgeProcessedElements(nodeSetToArray(elements || queryElements(settings))); 429 }; 430 431 var LazyLoad = function LazyLoad(customSettings, elements) { 432 this._settings = getInstanceSettings(customSettings); 433 this._loadingCount = 0; 434 setObserver(this); 435 this.update(elements); 436 }; 437 438 LazyLoad.prototype = { 439 update: function update(elements) { 440 var _this = this; 441 442 var settings = this._settings; 443 this._elements = getElements(elements, settings); 444 445 if (isBot || !this._observer) { 446 this.loadAll(); 447 return; 448 } 449 450 if (shouldUseNative(settings)) { 451 loadAllNative(this); 452 this._elements = getElements(elements, settings); 453 } 454 455 this._elements.forEach(function (element) { 456 _this._observer.observe(element); 457 }); 458 }, 459 destroy: function destroy() { 460 var _this2 = this; 461 462 if (this._observer) { 463 this._elements.forEach(function (element) { 464 _this2._observer.unobserve(element); 465 }); 466 467 this._observer = null; 468 } 469 470 this._elements = null; 471 this._settings = null; 472 }, 473 load: function load(element, force) { 474 revealElement(element, this, force); 475 }, 476 loadAll: function loadAll() { 477 var _this3 = this; 478 479 this._elements.forEach(function (element) { 480 revealAndUnobserve(element, _this3); 481 }); 482 } 483 }; 484 /* Automatic instances creation if required (useful for async script loading) */ 485 486 if (runningOnBrowser) { 487 autoInitialize(LazyLoad, window.lazyLoadOptions); 488 } 489 490 return LazyLoad; 491});
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.