PluginProbe ʕ •ᴥ•ʔ
10Web Booster – Website speed optimization, Cache & Page Speed optimizer / trunk
10Web Booster – Website speed optimization, Cache & Page Speed optimizer vtrunk
2.33.0 2.30.5 2.30.7 2.30.9 2.31.10 2.31.8 2.32.11 2.32.21 2.32.3 2.32.4 2.32.7 2.6.31 2.6.40 2.6.42 2.6.7 2.7.37 2.7.44 2.7.47 2.8.18 2.8.19 2.8.32 2.8.34 2.8.35 2.9.23 2.9.24 2.9.25 2.9.27 v2.27.4 trunk 2.0.10 2.0.11 2.0.12 2.0.13 2.0.14 2.0.15 2.0.17 2.0.18 2.0.21 2.0.22 2.0.25 2.0.26 2.0.27 2.0.3 2.0.7 2.0.9 2.10.46 2.10.65 2.10.66 2.10.68 2.11.41 2.11.42 2.11.43 2.12.15 2.12.21 2.12.22 2.12.23 2.12.26 2.13.37 2.13.40 2.13.41 2.13.42 2.13.44 2.13.45 2.13.47 2.14.49 2.14.50 2.15.18 2.17.21 2.17.23 2.18.17 2.19.44 2.19.45 2.19.46 2.19.49 2.2.12 2.2.15 2.2.16 2.2.18 2.2.8 2.20.31 2.20.32 2.20.33 2.21.11 2.21.12 2.21.16 2.21.25 2.22.32 2.23.13 2.23.15 2.23.16 2.23.18 2.24.12 2.24.14 2.24.18 2.25.14 2.26.6 2.28.10 2.28.13 2.28.14 2.28.7 2.29.1 2.29.2 2.29.3 2.3.0 2.3.1 2.3.2 2.3.3 2.30.18
tenweb-speed-optimizer / includes / external / js / jquery.lazy.js
tenweb-speed-optimizer / includes / external / js Last commit date
vanilla-lazyload 2 months ago jquery.lazy.av.min.js 4 years ago jquery.lazy.iframe.min.js 4 years ago jquery.lazy.js 3 years ago jquery.lazy.min.js 3 years ago lazyload.min.js 4 years ago loader.js 3 years ago two_delay.js 2 years ago two_elementor_video_to_iframe.js 4 years ago two_lazyload.js 3 years ago two_merge_google_font_faces.js 3 years ago two_worker.js 2 years ago two_yt_vi_lazyload.js 3 years ago two_yt_vi_lazyload.min.js 3 years ago
jquery.lazy.js
876 lines
1 /*!
2 * jQuery & Zepto Lazy - v1.7.10
3 * http://jquery.eisbehr.de/lazy/
4 *
5 * Copyright 2012 - 2018, Daniel 'Eisbehr' Kern
6 *
7 * Dual licensed under the MIT and GPL-2.0 licenses:
8 * http://www.opensource.org/licenses/mit-license.php
9 * http://www.gnu.org/licenses/gpl-2.0.html
10 *
11 * $("img.lazy").lazy();
12 */
13
14 ;(function(window, undefined) {
15 "use strict";
16
17 // noinspection JSUnresolvedVariable
18 /**
19 * library instance - here and not in construct to be shorter in minimization
20 * @return void
21 */
22 var $ = window.jQuery || window.Zepto,
23
24 /**
25 * unique plugin instance id counter
26 * @type {number}
27 */
28 lazyInstanceId = 0,
29
30 /**
31 * helper to register window load for jQuery 3
32 * @type {boolean}
33 */
34 windowLoaded = false;
35
36 /**
37 * make lazy available to jquery - and make it a bit more case-insensitive :)
38 * @access public
39 * @type {function}
40 * @param {object} settings
41 * @return {LazyPlugin}
42 */
43 $.fn.Lazy = $.fn.lazy = function(settings) {
44 return new LazyPlugin(this, settings);
45 };
46
47 /**
48 * helper to add plugins to lazy prototype configuration
49 * @access public
50 * @type {function}
51 * @param {string|Array} names
52 * @param {string|Array|function} [elements]
53 * @param {function} loader
54 * @return void
55 */
56 $.Lazy = $.lazy = function(names, elements, loader) {
57 // make second parameter optional
58 if ($.isFunction(elements)) {
59 loader = elements;
60 elements = [];
61 }
62
63 // exit here if parameter is not a callable function
64 if (!$.isFunction(loader)) {
65 return;
66 }
67
68 // make parameters an array of names to be sure
69 names = $.isArray(names) ? names : [names];
70 elements = $.isArray(elements) ? elements : [elements];
71
72 var config = LazyPlugin.prototype.config,
73 forced = config._f || (config._f = {});
74
75 // add the loader plugin for every name
76 for (var i = 0, l = names.length; i < l; i++) {
77 if (config[names[i]] === undefined || $.isFunction(config[names[i]])) {
78 config[names[i]] = loader;
79 }
80 }
81
82 // add forced elements loader
83 for (var c = 0, a = elements.length; c < a; c++) {
84 forced[elements[c]] = names[0];
85 }
86 };
87
88 /**
89 * contains all logic and the whole element handling
90 * is packed in a private function outside class to reduce memory usage, because it will not be created on every plugin instance
91 * @access private
92 * @type {function}
93 * @param {LazyPlugin} instance
94 * @param {object} config
95 * @param {object|Array} items
96 * @param {object} events
97 * @param {string} namespace
98 * @return void
99 */
100 function _executeLazy(instance, config, items, events, namespace) {
101 /**
102 * a helper to trigger the 'onFinishedAll' callback after all other events
103 * @access private
104 * @type {number}
105 */
106 var _awaitingAfterLoad = 0,
107
108 /**
109 * visible content width
110 * @access private
111 * @type {number}
112 */
113 _actualWidth = -1,
114
115 /**
116 * visible content height
117 * @access private
118 * @type {number}
119 */
120 _actualHeight = -1,
121
122 /**
123 * determine possibly detected high pixel density
124 * @access private
125 * @type {boolean}
126 */
127 _isRetinaDisplay = false,
128
129 /**
130 * dictionary entry for better minimization
131 * @access private
132 * @type {string}
133 */
134 _afterLoad = 'afterLoad',
135
136 /**
137 * dictionary entry for better minimization
138 * @access private
139 * @type {string}
140 */
141 _load = 'load',
142
143 /**
144 * dictionary entry for better minimization
145 * @access private
146 * @type {string}
147 */
148 _error = 'error',
149
150 /**
151 * dictionary entry for better minimization
152 * @access private
153 * @type {string}
154 */
155 _img = 'img',
156
157 /**
158 * dictionary entry for better minimization
159 * @access private
160 * @type {string}
161 */
162 _src = 'src',
163
164 /**
165 * dictionary entry for better minimization
166 * @access private
167 * @type {string}
168 */
169 _srcset = 'srcset',
170
171 /**
172 * dictionary entry for better minimization
173 * @access private
174 * @type {string}
175 */
176 _sizes = 'sizes',
177
178 /**
179 * dictionary entry for better minimization
180 * @access private
181 * @type {string}
182 */
183 _backgroundImage = 'background-image';
184
185 /**
186 * initialize plugin
187 * bind loading to events or set delay time to load all items at once
188 * @access private
189 * @return void
190 */
191 function _initialize() {
192 // detect actual device pixel ratio
193 // noinspection JSUnresolvedVariable
194 _isRetinaDisplay = window.devicePixelRatio > 1;
195
196 // prepare all initial items
197 items = _prepareItems(items);
198
199 // if delay time is set load all items at once after delay time
200 if (config.delay >= 0) {
201 setTimeout(function() {
202 _lazyLoadItems(true);
203 }, config.delay);
204 }
205
206 // if no delay is set or combine usage is active bind events
207 if (config.delay < 0 || config.combined) {
208 // create unique event function
209 events.e = _throttle(config.throttle, function(event) {
210 // reset detected window size on resize event
211 if (event.type === 'resize') {
212 _actualWidth = _actualHeight = -1;
213 }
214
215 // execute 'lazy magic'
216 _lazyLoadItems(event.all);
217 });
218
219 // create function to add new items to instance
220 events.a = function(additionalItems) {
221 additionalItems = _prepareItems(additionalItems);
222 items.push.apply(items, additionalItems);
223 };
224
225 // create function to get all instance items left
226 events.g = function() {
227 // filter loaded items before return in case internal filter was not running until now
228 return (items = $(items).filter(function() {
229 return !$(this).data(config.loadedName);
230 }));
231 };
232
233 // create function to force loading elements
234 events.f = function(forcedItems) {
235 for (var i = 0; i < forcedItems.length; i++) {
236 // only handle item if available in current instance
237 // use a compare function, because Zepto can't handle object parameter for filter
238 // var item = items.filter(forcedItems[i]);
239 /* jshint loopfunc: true */
240 var item = items.filter(function() {
241 return this === forcedItems[i];
242 });
243
244 if (item.length) {
245 _lazyLoadItems(false, item);
246 }
247 }
248 };
249
250 // load initial items
251 _lazyLoadItems();
252
253 // bind lazy load functions to scroll and resize event
254 // noinspection JSUnresolvedVariable
255 $(config.appendScroll).on('scroll.' + namespace + ' resize.' + namespace, events.e);
256 }
257 }
258
259 /**
260 * prepare items before handle them
261 * @access private
262 * @param {Array|object|jQuery} items
263 * @return {Array|object|jQuery}
264 */
265 function _prepareItems(items) {
266 // fetch used configurations before loops
267 var defaultImage = config.defaultImage,
268 placeholder = config.placeholder,
269 imageBase = config.imageBase,
270 srcsetAttribute = config.srcsetAttribute,
271 loaderAttribute = config.loaderAttribute,
272 forcedTags = config._f || {};
273
274 // filter items and only add those who not handled yet and got needed attributes available
275 items = $(items).filter(function() {
276 var element = $(this),
277 tag = _getElementTagName(this);
278
279 return !element.data(config.handledName) &&
280 (element.attr(config.attribute) || element.attr(srcsetAttribute) || element.attr(loaderAttribute) || forcedTags[tag] !== undefined);
281 })
282
283 // append plugin instance to all elements
284 .data('plugin_' + config.name, instance);
285
286 for (var i = 0, l = items.length; i < l; i++) {
287 var element = $(items[i]),
288 tag = _getElementTagName(items[i]),
289 elementImageBase = element.attr(config.imageBaseAttribute) || imageBase;
290
291 // generate and update source set if an image base is set
292 if (tag === _img && elementImageBase && element.attr(srcsetAttribute)) {
293 element.attr(srcsetAttribute, _getCorrectedSrcSet(element.attr(srcsetAttribute), elementImageBase));
294 }
295
296 // add loader to forced element types
297 if (forcedTags[tag] !== undefined && !element.attr(loaderAttribute)) {
298 element.attr(loaderAttribute, forcedTags[tag]);
299 }
300
301 // set default image on every element without source
302 if (tag === _img && defaultImage && !element.attr(_src)) {
303 element.attr(_src, defaultImage);
304 }
305
306 // set placeholder on every element without background image
307 else if (tag !== _img && placeholder && (!element.css(_backgroundImage) || element.css(_backgroundImage) === 'none')) {
308 element.css(_backgroundImage, "url('" + placeholder + "')");
309 }
310 }
311
312 return items;
313 }
314
315 /**
316 * the 'lazy magic' - check all items
317 * @access private
318 * @param {boolean} [allItems]
319 * @param {object} [forced]
320 * @return void
321 */
322 function _lazyLoadItems(allItems, forced) {
323 // skip if no items where left
324 if (!items.length) {
325 // destroy instance if option is enabled
326 if (config.autoDestroy) {
327 // noinspection JSUnresolvedFunction
328 instance.destroy();
329 }
330
331 return;
332 }
333
334 var elements = forced || items,
335 loadTriggered = false,
336 imageBase = config.imageBase || '',
337 srcsetAttribute = config.srcsetAttribute,
338 handledName = config.handledName;
339
340 // loop all available items
341 for (var i = 0; i < elements.length; i++) {
342 // item is at least in loadable area
343 if (allItems || forced || _isInLoadableArea(elements[i])) {
344 var element = $(elements[i]),
345 tag = _getElementTagName(elements[i]),
346 attribute = element.attr(config.attribute),
347 elementImageBase = element.attr(config.imageBaseAttribute) || imageBase,
348 customLoader = element.attr(config.loaderAttribute);
349
350 // is not already handled
351 if (!element.data(handledName) &&
352 // and is visible or visibility doesn't matter
353 (!config.visibleOnly || element.is(':visible')) && (
354 // and image source or source set attribute is available
355 (attribute || element.attr(srcsetAttribute)) && (
356 // and is image tag where attribute is not equal source or source set
357 (tag === _img && (elementImageBase + attribute !== element.attr(_src) || element.attr(srcsetAttribute) !== element.attr(_srcset))) ||
358 // or is non image tag where attribute is not equal background
359 (tag !== _img && elementImageBase + attribute !== element.css(_backgroundImage))
360 ) ||
361 // or custom loader is available
362 customLoader))
363 {
364 // mark element always as handled as this point to prevent double handling
365 loadTriggered = true;
366 element.data(handledName, true);
367
368 // load item
369 _handleItem(element, tag, elementImageBase, customLoader);
370 }
371 }
372 }
373
374 // when something was loaded remove them from remaining items
375 if (loadTriggered) {
376 items = $(items).filter(function() {
377 return !$(this).data(handledName);
378 });
379 }
380 }
381
382 /**
383 * load the given element the lazy way
384 * @access private
385 * @param {object} element
386 * @param {string} tag
387 * @param {string} imageBase
388 * @param {function} [customLoader]
389 * @return void
390 */
391 function _handleItem(element, tag, imageBase, customLoader) {
392 // increment count of items waiting for after load
393 ++_awaitingAfterLoad;
394
395 // extended error callback for correct 'onFinishedAll' handling
396 var errorCallback = function() {
397 _triggerCallback('onError', element);
398 _reduceAwaiting();
399
400 // prevent further callback calls
401 errorCallback = $.noop;
402 };
403
404 // trigger function before loading image
405 _triggerCallback('beforeLoad', element);
406
407 // fetch all double used data here for better code minimization
408 var srcAttribute = config.attribute,
409 srcsetAttribute = config.srcsetAttribute,
410 sizesAttribute = config.sizesAttribute,
411 retinaAttribute = config.retinaAttribute,
412 removeAttribute = config.removeAttribute,
413 loadedName = config.loadedName,
414 elementRetina = element.attr(retinaAttribute);
415
416 // handle custom loader
417 if (customLoader) {
418 // on load callback
419 var loadCallback = function() {
420 // remove attribute from element
421 if (removeAttribute) {
422 element.removeAttr(config.loaderAttribute);
423 }
424
425 // mark element as loaded
426 element.data(loadedName, true);
427
428 // call after load event
429 _triggerCallback(_afterLoad, element);
430
431 // remove item from waiting queue and possibly trigger finished event
432 // it's needed to be asynchronous to run after filter was in _lazyLoadItems
433 setTimeout(_reduceAwaiting, 1);
434
435 // prevent further callback calls
436 loadCallback = $.noop;
437 };
438
439 // bind error event to trigger callback and reduce waiting amount
440 element.off(_error).one(_error, errorCallback)
441
442 // bind after load callback to element
443 .one(_load, loadCallback);
444
445 // trigger custom loader and handle response
446 if (!_triggerCallback(customLoader, element, function(response) {
447 if(response) {
448 element.off(_load);
449 loadCallback();
450 }
451 else {
452 element.off(_error);
453 errorCallback();
454 }
455 })) {
456 element.trigger(_error);
457 }
458 }
459
460 // handle images
461 else {
462 // create image object
463 var imageObj = $(new Image());
464
465 // bind error event to trigger callback and reduce waiting amount
466 imageObj.one(_error, errorCallback)
467
468 // bind after load callback to image
469 .one(_load, function() {
470 // remove element from view
471 element.hide();
472
473 // set image back to element
474 // do it as single 'attr' calls, to be sure 'src' is set after 'srcset'
475 if (tag === _img) {
476 element.attr(_sizes, imageObj.attr(_sizes))
477 .attr(_srcset, imageObj.attr(_srcset))
478 .attr(_src, imageObj.attr(_src));
479 }
480 else {
481 if(element.attr("data-full-bg-image")){
482 element.css(_backgroundImage, element.attr("data-full-bg-image"));
483 }else{
484 element.css(_backgroundImage, "url('" + imageObj.attr(_src) + "')");
485 }
486 }
487
488 // bring it back with some effect!
489 element[config.effect](config.effectTime);
490
491 // remove attribute from element
492 if (removeAttribute) {
493 element.removeAttr(srcAttribute + ' ' + srcsetAttribute + ' ' + retinaAttribute + ' ' + config.imageBaseAttribute);
494
495 // only remove 'sizes' attribute, if it was a custom one
496 if (sizesAttribute !== _sizes) {
497 element.removeAttr(sizesAttribute);
498 }
499 }
500
501 // mark element as loaded
502 element.data(loadedName, true);
503
504 // call after load event
505 _triggerCallback(_afterLoad, element);
506
507 // cleanup image object
508 imageObj.remove();
509
510 // remove item from waiting queue and possibly trigger finished event
511 _reduceAwaiting();
512 });
513
514 // set sources
515 // do it as single 'attr' calls, to be sure 'src' is set after 'srcset'
516 var imageSrc = (_isRetinaDisplay && elementRetina ? elementRetina : element.attr(srcAttribute)) || '';
517 imageObj.attr(_sizes, element.attr(sizesAttribute))
518 .attr(_srcset, element.attr(srcsetAttribute))
519 .attr(_src, imageSrc ? imageBase + imageSrc : null);
520
521 // call after load even on cached image
522 imageObj.complete && imageObj.trigger(_load); // jshint ignore : line
523 }
524 }
525
526 /**
527 * check if the given element is inside the current viewport or threshold
528 * @access private
529 * @param {object} element
530 * @return {boolean}
531 */
532 function _isInLoadableArea(element) {
533 var elementBound = element.getBoundingClientRect(),
534 direction = config.scrollDirection,
535 threshold = config.threshold,
536 vertical = // check if element is in loadable area from top
537 ((_getActualHeight() + threshold) > elementBound.top) &&
538 // check if element is even in loadable are from bottom
539 (-threshold < elementBound.bottom),
540 horizontal = // check if element is in loadable area from left
541 ((_getActualWidth() + threshold) > elementBound.left) &&
542 // check if element is even in loadable area from right
543 (-threshold < elementBound.right);
544
545 if (direction === 'vertical') {
546 return vertical;
547 }
548 else if (direction === 'horizontal') {
549 return horizontal;
550 }
551
552 return vertical && horizontal;
553 }
554
555 /**
556 * receive the current viewed width of the browser
557 * @access private
558 * @return {number}
559 */
560 function _getActualWidth() {
561 return _actualWidth >= 0 ? _actualWidth : (_actualWidth = $(window).width());
562 }
563
564 /**
565 * receive the current viewed height of the browser
566 * @access private
567 * @return {number}
568 */
569 function _getActualHeight() {
570 return _actualHeight >= 0 ? _actualHeight : (_actualHeight = $(window).height());
571 }
572
573 /**
574 * get lowercase tag name of an element
575 * @access private
576 * @param {object} element
577 * @returns {string}
578 */
579 function _getElementTagName(element) {
580 return element.tagName.toLowerCase();
581 }
582
583 /**
584 * prepend image base to all srcset entries
585 * @access private
586 * @param {string} srcset
587 * @param {string} imageBase
588 * @returns {string}
589 */
590 function _getCorrectedSrcSet(srcset, imageBase) {
591 if (imageBase) {
592 // trim, remove unnecessary spaces and split entries
593 var entries = srcset.split(',');
594 srcset = '';
595
596 for (var i = 0, l = entries.length; i < l; i++) {
597 srcset += imageBase + entries[i].trim() + (i !== l - 1 ? ',' : '');
598 }
599 }
600
601 return srcset;
602 }
603
604 /**
605 * helper function to throttle down event triggering
606 * @access private
607 * @param {number} delay
608 * @param {function} callback
609 * @return {function}
610 */
611 function _throttle(delay, callback) {
612 var timeout,
613 lastExecute = 0;
614
615 return function(event, ignoreThrottle) {
616 var elapsed = +new Date() - lastExecute;
617
618 function run() {
619 lastExecute = +new Date();
620 // noinspection JSUnresolvedFunction
621 callback.call(instance, event);
622 }
623
624 timeout && clearTimeout(timeout); // jshint ignore : line
625
626 if (elapsed > delay || !config.enableThrottle || ignoreThrottle) {
627 run();
628 }
629 else {
630 timeout = setTimeout(run, delay - elapsed);
631 }
632 };
633 }
634
635 /**
636 * reduce count of awaiting elements to 'afterLoad' event and fire 'onFinishedAll' if reached zero
637 * @access private
638 * @return void
639 */
640 function _reduceAwaiting() {
641 --_awaitingAfterLoad;
642
643 // if no items were left trigger finished event
644 if (!items.length && !_awaitingAfterLoad) {
645 _triggerCallback('onFinishedAll');
646 }
647 }
648
649 /**
650 * single implementation to handle callbacks, pass element and set 'this' to current instance
651 * @access private
652 * @param {string|function} callback
653 * @param {object} [element]
654 * @param {*} [args]
655 * @return {boolean}
656 */
657 function _triggerCallback(callback, element, args) {
658 if ((callback = config[callback])) {
659 // jQuery's internal '$(arguments).slice(1)' are causing problems at least on old iPads
660 // below is shorthand of 'Array.prototype.slice.call(arguments, 1)'
661 callback.apply(instance, [].slice.call(arguments, 1));
662 return true;
663 }
664
665 return false;
666 }
667
668 // if event driven or window is already loaded don't wait for page loading
669 if (config.bind === 'event' || windowLoaded) {
670 _initialize();
671 }
672
673 // otherwise load initial items and start lazy after page load
674 else {
675 // noinspection JSUnresolvedVariable
676 $(window).on(_load + '.' + namespace, _initialize);
677 }
678 }
679
680 /**
681 * lazy plugin class constructor
682 * @constructor
683 * @access private
684 * @param {object} elements
685 * @param {object} settings
686 * @return {object|LazyPlugin}
687 */
688 function LazyPlugin(elements, settings) {
689 /**
690 * this lazy plugin instance
691 * @access private
692 * @type {object|LazyPlugin|LazyPlugin.prototype}
693 */
694 var _instance = this,
695
696 /**
697 * this lazy plugin instance configuration
698 * @access private
699 * @type {object}
700 */
701 _config = $.extend({}, _instance.config, settings),
702
703 /**
704 * instance generated event executed on container scroll or resize
705 * packed in an object to be referenceable and short named because properties will not be minified
706 * @access private
707 * @type {object}
708 */
709 _events = {},
710
711 /**
712 * unique namespace for instance related events
713 * @access private
714 * @type {string}
715 */
716 _namespace = _config.name + '-' + (++lazyInstanceId);
717
718 // noinspection JSUndefinedPropertyAssignment
719 /**
720 * wrapper to get or set an entry from plugin instance configuration
721 * much smaller on minify as direct access
722 * @access public
723 * @type {function}
724 * @param {string} entryName
725 * @param {*} [value]
726 * @return {LazyPlugin|*}
727 */
728 _instance.config = function(entryName, value) {
729 if (value === undefined) {
730 return _config[entryName];
731 }
732
733 _config[entryName] = value;
734 return _instance;
735 };
736
737 // noinspection JSUndefinedPropertyAssignment
738 /**
739 * add additional items to current instance
740 * @access public
741 * @param {Array|object|string} items
742 * @return {LazyPlugin}
743 */
744 _instance.addItems = function(items) {
745 _events.a && _events.a($.type(items) === 'string' ? $(items) : items); // jshint ignore : line
746 return _instance;
747 };
748
749 // noinspection JSUndefinedPropertyAssignment
750 /**
751 * get all left items of this instance
752 * @access public
753 * @returns {object}
754 */
755 _instance.getItems = function() {
756 return _events.g ? _events.g() : {};
757 };
758
759 // noinspection JSUndefinedPropertyAssignment
760 /**
761 * force lazy to load all items in loadable area right now
762 * by default without throttle
763 * @access public
764 * @type {function}
765 * @param {boolean} [useThrottle]
766 * @return {LazyPlugin}
767 */
768 _instance.update = function(useThrottle) {
769 _events.e && _events.e({}, !useThrottle); // jshint ignore : line
770 return _instance;
771 };
772
773 // noinspection JSUndefinedPropertyAssignment
774 /**
775 * force element(s) to load directly, ignoring the viewport
776 * @access public
777 * @param {Array|object|string} items
778 * @return {LazyPlugin}
779 */
780 _instance.force = function(items) {
781 _events.f && _events.f($.type(items) === 'string' ? $(items) : items); // jshint ignore : line
782 return _instance;
783 };
784
785 // noinspection JSUndefinedPropertyAssignment
786 /**
787 * force lazy to load all available items right now
788 * this call ignores throttling
789 * @access public
790 * @type {function}
791 * @return {LazyPlugin}
792 */
793 _instance.loadAll = function() {
794 _events.e && _events.e({all: true}, true); // jshint ignore : line
795 return _instance;
796 };
797
798 // noinspection JSUndefinedPropertyAssignment
799 /**
800 * destroy this plugin instance
801 * @access public
802 * @type {function}
803 * @return undefined
804 */
805 _instance.destroy = function() {
806 // unbind instance generated events
807 // noinspection JSUnresolvedFunction, JSUnresolvedVariable
808 $(_config.appendScroll).off('.' + _namespace, _events.e);
809 // noinspection JSUnresolvedVariable
810 $(window).off('.' + _namespace);
811
812 // clear events
813 _events = {};
814
815 return undefined;
816 };
817
818 // start using lazy and return all elements to be chainable or instance for further use
819 // noinspection JSUnresolvedVariable
820 _executeLazy(_instance, _config, elements, _events, _namespace);
821 return _config.chainable ? elements : _instance;
822 }
823
824 /**
825 * settings and configuration data
826 * @access public
827 * @type {object|*}
828 */
829 LazyPlugin.prototype.config = {
830 // general
831 name : 'lazy',
832 chainable : true,
833 autoDestroy : true,
834 bind : 'load',
835 threshold : 500,
836 visibleOnly : false,
837 appendScroll : window,
838 scrollDirection : 'both',
839 imageBase : null,
840 defaultImage : 'data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==',
841 placeholder : null,
842 delay : -1,
843 combined : false,
844
845 // attributes
846 attribute : 'data-src',
847 srcsetAttribute : 'data-srcset',
848 sizesAttribute : 'data-sizes',
849 retinaAttribute : 'data-retina',
850 loaderAttribute : 'data-loader',
851 imageBaseAttribute : 'data-imagebase',
852 removeAttribute : true,
853 handledName : 'handled',
854 loadedName : 'loaded',
855
856 // effect
857 effect : 'show',
858 effectTime : 0,
859
860 // throttle
861 enableThrottle : true,
862 throttle : 250,
863
864 // callbacks
865 beforeLoad : undefined,
866 afterLoad : undefined,
867 onError : undefined,
868 onFinishedAll : undefined
869 };
870
871 // register window load event globally to prevent not loading elements
872 // since jQuery 3.X ready state is fully async and may be executed after 'load'
873 $(window).on('load', function() {
874 windowLoaded = true;
875 });
876 })(window);