PageSourceSearch

https://tsenghungchen.github.io/show_adapt_tell/jquery.lazyloadxt.extra.js

js tsenghungchen.github.io collected 2026-10-03 10:06:31 UTC 10,353 bytes, 343 lines download raw bytes

vendor: 10,353 bytes, lines 1-343
1/*! Lazy Load XT v1.1.0 2016-01-12
2 * http://ressio.github.io/lazy-load-xt
3 * (C) 2016 RESS.io
4 * Licensed under MIT */
5
6(function ($, window, document, undefined) {
7    // options
8    var lazyLoadXT = 'lazyLoadXT',
9        dataLazied = 'lazied',
10        load_error = 'load error',
11        classLazyHidden = 'lazy-hidden',
12        docElement = document.documentElement || document.body,
13    //  force load all images in Opera Mini and some mobile browsers without scroll event or getBoundingClientRect()
14        forceLoad = (window.onscroll === undefined || !!window.operamini || !docElement.getBoundingClientRect),
15        options = {
16            autoInit: true, // auto initialize in $.ready
17            selector: 'img[data-src]', // selector for lazyloading elements
18            blankImage: 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7',
19            throttle: 99, // interval (ms) for changes check
20            forceLoad: forceLoad, // force auto load all images
21
22            loadEvent: 'pageshow', // check AJAX-loaded content in jQueryMobile
23            updateEvent: 'load orientationchange resize scroll touchmove focus', // page-modified events
24            forceEvent: 'lazyloadall', // force loading of all elements
25
26            //onstart: null,
27            oninit: {removeClass: 'lazy'}, // init handler
28            onshow: {addClass: classLazyHidden}, // start loading handler
29            onload: {removeClass: classLazyHidden, addClass: 'lazy-loaded'}, // load success handler
30            onerror: {removeClass: classLazyHidden}, // error handler
31            //oncomplete: null, // complete handler
32
33            //scrollContainer: undefined,
34            checkDuplicates: true
35        },
36        elementOptions = {
37            srcAttr: 'data-src',
38            edgeX: 0,
39            edgeY: 0,
40            visibleOnly: true
41        },
42        $window = $(window),
43        $isFunction = $.isFunction,
44        $extend = $.extend,
45        $data = $.data || function (el, name) {
46            return $(el).data(name);
47        },
48        elements = [],
49        topLazy = 0,
50    /*
51     waitingMode=0 : no setTimeout
52     waitingMode=1 : setTimeout, no deferred events
53     waitingMode=2 : setTimeout, deferred events
54     */
55        waitingMode = 0;
56
57    $[lazyLoadXT] = $extend(options, elementOptions, $[lazyLoadXT]);
58
59    /**
60     * Return options.prop if obj.prop is undefined, otherwise return obj.prop
61     * @param {*} obj
62     * @param {*} prop
63     * @returns *
64     */
65    function getOrDef(obj, prop) {
66        return obj[prop] === undefined ? options[prop] : obj[prop];
67    }
68
69    /**
70     * @returns {number}
71     */
72    function scrollTop() {
73        var scroll = window.pageYOffset;
74        return (scroll === undefined) ? docElement.scrollTop : scroll;
75    }
76
77    /**
78     * Add new elements to lazy-load list:
79     * $(elements).lazyLoadXT() or $(window).lazyLoadXT()
80     *
81     * @param {object} [overrides] override global options
82     */
83    $.fn[lazyLoadXT] = function (overrides) {
84        overrides = overrides || {};
85
86        var blankImage = getOrDef(overrides, 'blankImage'),
87            checkDuplicates = getOrDef(overrides, 'checkDuplicates'),
88            scrollContainer = getOrDef(overrides, 'scrollContainer'),
89            forceShow = getOrDef(overrides, 'show'),
90            elementOptionsOverrides = {},
91            prop;
92
93        // empty overrides.scrollContainer is supported by both jQuery and Zepto
94        $(scrollContainer).on('scroll', queueCheckLazyElements);
95
96        for (prop in elementOptions) {
97            elementOptionsOverrides[prop] = getOrDef(overrides, prop);
98        }
99
100        return this.each(function (index, el) {
101            if (el === window) {
102                $(options.selector).lazyLoadXT(overrides);
103            } else {
104                var duplicate = checkDuplicates && $data(el, dataLazied),
105                    $el = $(el).data(dataLazied, forceShow ? -1 : 1);
106
107                // prevent duplicates
108                if (duplicate) {
109                    queueCheckLazyElements();
110                    return;
111                }
112
113                if (blankImage && el.tagName === 'IMG' && !el.src) {
114                    el.src = blankImage;
115                }
116
117                // clone elementOptionsOverrides object
118                $el[lazyLoadXT] = $extend({}, elementOptionsOverrides);
119
120                triggerEvent('init', $el);
121
122                elements.push($el);
123                queueCheckLazyElements();
124            }
125        });
126    };
127
128
129    /**
130     * Process function/object event handler
131     * @param {string} event suffix
132     * @param {jQuery} $el
133     */
134    function triggerEvent(event, $el) {
135        var handler = options['on' + event];
136        if (handler) {
137            if ($isFunction(handler)) {
138                handler.call($el[0]);
139            } else {
140                if (handler.addClass) {
141                    $el.addClass(handler.addClass);
142                }
143                if (handler.removeClass) {
144                    $el.removeClass(handler.removeClass);
145                }
146            }
147        }
148
149        $el.trigger('lazy' + event, [$el]);
150
151        // queue next check as images may be resized after loading of actual file
152        queueCheckLazyElements();
153    }
154
155
156    /**
157     * Trigger onload/onerror handler
158     * @param {Event} e
159     */
160    function triggerLoadOrError(e) {
161        triggerEvent(e.type, $(this).off(load_error, triggerLoadOrError));
162    }
163
164
165    /**
166     * Load visible elements
167     * @param {bool} [force] loading of all elements
168     */
169    function checkLazyElements(force) {
170        if (!elements.length) {
171            return;
172        }
173
174        force = force || options.forceLoad;
175
176        topLazy = Infinity;
177
178        var viewportTop = scrollTop(),
179            viewportHeight = window.innerHeight || docElement.clientHeight,
180            viewportWidth = window.innerWidth || docElement.clientWidth,
181            i,
182            length;
183
184        for (i = 0, length = elements.length; i < length; i++) {
185            var $el = elements[i],
186                el = $el[0],
187                objData = $el[lazyLoadXT],
188                removeNode = false,
189                visible = force || $data(el, dataLazied) < 0,
190                topEdge;
191
192            // remove items that are not in DOM
193            if (!$.contains(docElement, el)) {
194                removeNode = true;
195            } else if (force || !objData.visibleOnly || el.offsetWidth || el.offsetHeight) {
196
197                if (!visible) {
198                    var elPos = el.getBoundingClientRect(),
199                        edgeX = objData.edgeX,
200                        edgeY = objData.edgeY;
201
202                    topEdge = (elPos.top + viewportTop - edgeY) - viewportHeight;
203
204                    visible = (topEdge <= viewportTop && elPos.bottom > -edgeY &&
205                        elPos.left <= viewportWidth + edgeX && elPos.right > -edgeX);
206                }
207
208                if (visible) {
209                    $el.on(load_error, triggerLoadOrError);
210
211                    triggerEvent('show', $el);
212
213                    var srcAttr = objData.srcAttr,
214                        src = $isFunction(srcAttr) ? srcAttr($el) : el.getAttribute(srcAttr);
215
216                    if (src) {
217                        el.src = src;
218                    }
219
220                    removeNode = true;
221                } else {
222                    if (topEdge < topLazy) {
223                        topLazy = topEdge;
224                    }
225                }
226            }
227
228            if (removeNode) {
229                $data(el, dataLazied, 0);
230                elements.splice(i--, 1);
231                length--;
232            }
233        }
234
235        if (!length) {
236            triggerEvent('complete', $(docElement));
237        }
238    }
239
240
241    /**
242     * Run check of lazy elements after timeout
243     */
244    function timeoutLazyElements() {
245        if (waitingMode > 1) {
246            waitingMode = 1;
247            checkLazyElements();
248            setTimeout(timeoutLazyElements, options.throttle);
249        } else {
250            waitingMode = 0;
251        }
252    }
253
254
255    /**
256     * Queue check of lazy elements because of event e
257     * @param {Event} [e]
258     */
259    function queueCheckLazyElements(e) {
260        if (!elements.length) {
261            return;
262        }
263
264        // fast check for scroll event without new visible elements
265        if (e && e.type === 'scroll' && e.currentTarget === window) {
266            if (topLazy >= scrollTop()) {
267                return;
268            }
269        }
270
271        if (!waitingMode) {
272            setTimeout(timeoutLazyElements, 0);
273        }
274        waitingMode = 2;
275    }
276
277
278    /**
279     * Initialize list of hidden elements
280     */
281    function initLazyElements() {
282        $window.lazyLoadXT();
283    }
284
285
286    /**
287     * Loading of all elements
288     */
289    function forceLoadAll() {
290        checkLazyElements(true);
291    }
292
293
294    /**
295     * Initialization
296     */
297    $(document).ready(function () {
298        triggerEvent('start', $window);
299
300        $window
301            .on(options.updateEvent, queueCheckLazyElements)
302            .on(options.forceEvent, forceLoadAll);
303
304        $(document).on(options.updateEvent, queueCheckLazyElements);
305
306        if (options.autoInit) {
307            $window.on(options.loadEvent, initLazyElements);
308            initLazyElements(); // standard initialization
309        }
310    });
311
312})(window.jQuery || window.Zepto || window.$, window, document);
313
314
315(function ($) {
316    var options = $.lazyLoadXT;
317
318    options.selector += ',video,iframe[data-src]';
319    options.videoPoster = 'data-poster';
320
321    $(document).on('lazyshow', 'video', function (e, $el) {
322        var srcAttr = $el.lazyLoadXT.srcAttr,
323            isFuncSrcAttr = $.isFunction(srcAttr),
324            changed = false;
325
326        $el.attr('poster', $el.attr(options.videoPoster));
327        $el.children('source,track')
328            .each(function (index, el) {
329                var $child = $(el),
330                    src = isFuncSrcAttr ? srcAttr($child) : $child.attr(srcAttr);
331                if (src) {
332                    $child.attr('src', src);
333                    changed = true;
334                }
335            });
336
337        // reload video
338        if (changed) {
339            this.load();
340        }
341    });
342
343})(window.jQuery || window.Zepto || window.$);

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.