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 41 var dataPrefix = "data-"; 42 var processedDataName = "was-processed"; 43 var timeoutDataName = "ll-timeout"; 44 var trueString = "true"; 45 46 var getData = function getData(element, attribute) { 47 return element.getAttribute(dataPrefix + attribute); 48 }; 49 50 var setData = function setData(element, attribute, value) { 51 var attrName = dataPrefix + attribute; 52 53 if (value === null) { 54 element.removeAttribute(attrName); 55 return; 56 } 57 58 element.setAttribute(attrName, value); 59 }; 60 61 var setWasProcessedData = function setWasProcessedData(element) { 62 return setData(element, processedDataName, trueString); 63 }; 64 65 var getWasProcessedData = function getWasProcessedData(element) { 66 return getData(element, processedDataName) === trueString; 67 }; 68 69 var setTimeoutData = function setTimeoutData(element, value) { 70 return setData(element, timeoutDataName, value); 71 }; 72 73 var getTimeoutData = function getTimeoutData(element) { 74 return getData(element, timeoutDataName); 75 }; 76 77 var purgeProcessedElements = function purgeProcessedElements(elements) { 78 return elements.filter(function (element) { 79 return !getWasProcessedData(element); 80 }); 81 }; 82 83 var purgeOneElement = function purgeOneElement(elements, elementToPurge) { 84 return elements.filter(function (element) { 85 return element !== elementToPurge; 86 }); 87 }; 88 /* Creates instance and notifies it through the window element */ 89 90 91 var createInstance = function createInstance(classObj, options) { 92 var event; 93 var eventString = "LazyLoad::Initialized"; 94 var instance = new classObj(options); 95 96 try { 97 // Works in modern browsers 98 event = new CustomEvent(eventString, { 99 detail: { 100 instance: instance 101 } 102 }); 103 } catch (err) { 104 // Works in Internet Explorer (all versions) 105 event = document.createEvent("CustomEvent"); 106 event.initCustomEvent(eventString, false, false, { 107 instance: instance 108 }); 109 } 110 111 window.dispatchEvent(event); 112 }; 113 /* Auto initialization of one or more instances of lazyload, depending on the 114 options passed in (plain object or an array) */ 115 116 117 function autoInitialize(classObj, options) { 118 if (!options) { 119 return; 120 } 121 122 if (!options.length) { 123 // Plain object 124 createInstance(classObj, options); 125 } else { 126 // Array of objects 127 for (var i = 0, optionsItem; optionsItem = options[i]; i += 1) { 128 createInstance(classObj, optionsItem); 129 } 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); // Still useful for elements other than IMG and IFRAME 435 436 this.update(elements); 437 }; 438 439 LazyLoad.prototype = { 440 update: function update(elements) { 441 var _this = this; 442 443 var settings = this._settings; 444 this._elements = getElements(elements, settings); 445 446 if (isBot || !this._observer) { 447 this.loadAll(); 448 return; 449 } 450 451 if (shouldUseNative(settings)) { 452 loadAllNative(this); 453 this._elements = getElements(elements, settings); 454 } 455 456 this._elements.forEach(function (element) { 457 _this._observer.observe(element); 458 }); 459 }, 460 destroy: function destroy() { 461 var _this2 = this; 462 463 if (this._observer) { 464 this._elements.forEach(function (element) { 465 _this2._observer.unobserve(element); 466 }); 467 468 this._observer = null; 469 } 470 471 this._elements = null; 472 this._settings = null; 473 }, 474 load: function load(element, force) { 475 revealElement(element, this, force); 476 }, 477 loadAll: function loadAll() { 478 var _this3 = this; 479 480 this._elements.forEach(function (element) { 481 revealAndUnobserve(element, _this3); 482 }); 483 } 484 }; 485 /* Automatic instances creation if required (useful for async script loading) */ 486 487 if (runningOnBrowser) { 488 autoInitialize(LazyLoad, window.lazyLoadOptions); 489 } 490 491 return LazyLoad; 492});
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.