PageSourceSearch

https://www.secretchina.com/scripts/jquery/jquery.lazy.js

js secretchina.com collected 2026-10-02 02:25:55 UTC 11,551 bytes, 315 lines download raw bytes

1/*!
2 * jQuery Lazy - v0.1.19
3 * http://jquery.eisbehr.de/lazy/
4 * http://eisbehr.de
5 *
6 * Copyright 2014, Daniel 'Eisbehr' Kern
7 *
8 * Dual licensed under the MIT and GPL v2 licenses:
9 * http://www.opensource.org/licenses/mit-license.php
10 * http://www.gnu.org/licenses/gpl-2.0.html
11 *
12 * jQuery("img.lazy").lazy();
13 */
14
15(function($, window, document, undefined)
16{
17    $.fn.lazy = function(settings)
18    {
19        /**
20         * settings and configuration data
21         * @type {}
22         */
23        var configuration =
24        {
25            // general
26            bind            : "load",
27            //threshold       : 500,
28            threshold       : 0, //change by steve
29            fallbackHeight  : 2000,
30            visibleOnly     : true,
31            appendScroll    : window,
32
33            // delay
34            delay           : -1,
35            combined        : false,
36
37            // attribute
38            attribute       : "data-src",
39            removeAttribute : true,
40
41            // effect
42            effect          : "show",
43            effectTime      : 0,
44
45            // throttle
46            enableThrottle  : false,
47            throttle        : 250,
48
49            // callback
50            beforeLoad      : null,
51            onLoad          : null,
52            afterLoad       : null,
53            onError         : null,
54            onFinishedAll   : null
55        };
56
57        // overwrite configuration with custom user settings
58        if( settings ) $.extend(configuration, settings);
59
60        // all given items by jQuery selector
61        var items = this;
62
63        // a helper to trigger the onFinishedAll after all other events
64        var awaitingAfterLoad = 0;
65
66        // on first page load get initial images
67        if( configuration.bind == "load" ) $(window).load(_init);
68
69        // if event driven don't wait for page loading
70        else if( configuration.bind == "event" ) _init();
71
72        // bind error callback to images if wanted
73        if( configuration.onError ) items.bind("error", function() { _triggerCallback(configuration.onError, $(this)); });
74
75        /**
76         * lazyLoadImages(allImages)
77         *
78         * the 'lazy magic'
79         * check and load all needed images
80         *
81         * @param allImages boolean
82         * @return void
83         */
84        function lazyLoadImages(allImages)
85        {
86            if( typeof allImages != "boolean" ) allImages = false;
87
88            items.each(function()
89            {
90                var element = $(this);
91                var tag = this.tagName.toLowerCase();
92
93                if( _isInLoadableArea(element) || allImages )
94                {
95                    // the lazy magic
96                    if( // image source attribute is available
97                        element.attr(configuration.attribute) &&
98                        // and is image tag where attribute is not equal source 
99                        ((tag == "img" && element.attr(configuration.attribute) != element.attr("src")) ||
100                        // or is non image tag where attribute is not equal background
101                        ((tag != "img" && element.attr(configuration.attribute) != element.css("background-image"))) ) &&
102                        // and is not actually loaded just before
103                        !element.data('status') &&
104                        // and is visible or visibility doesn't matter
105                        (element.is(":visible") || !configuration.visibleOnly) )
106                    {
107                        // create image object						
108                        var imageObj = $(new Image());
109
110                        // increment count of items waiting for after load
111                        ++awaitingAfterLoad;
112
113                        // bind error event if wanted, otherwise only reduce waiting count
114                        if(configuration.onError) imageObj.error(function() { element.data("status", ''); _triggerCallback(configuration.onError, element); _reduceAwaiting(); });
115                        else imageObj.error(function() { element.data("status", ''); _reduceAwaiting(); });
116
117                        // bind after load callback to image
118                        var onLoad = true;
119                        imageObj.one("load", function()
120                        {
121                            var callable = function()
122                            {
123                                if( onLoad )
124                                {
125                                    window.setTimeout(callable, 100);
126                                    return;
127                                }
128
129                                // remove element from view
130                                element.hide();
131
132                                // set image back to element
133                                if( tag == "img" ) element.attr("src", imageObj.attr("src"));
134                                else element.css("background-image", "url(" + imageObj.attr("src") + ")");
135
136                                // bring it back with some effect!
137                                element[configuration.effect](configuration.effectTime);
138
139                                // remove attribute from element
140                                if( configuration.removeAttribute ) element.removeAttr(configuration.attribute);
141
142                                // call after load event
143                                _triggerCallback(configuration.afterLoad, element);
144                                element.data("status", "loaded");
145
146                                // unbind event and remove image object
147                                imageObj.unbind("load");
148                                imageObj.remove();
149
150                                // remove item from waiting cue and possible trigger finished event
151                                _reduceAwaiting();
152                            };
153
154                            callable();
155                        });
156
157                        // trigger function before loading image
158                        _triggerCallback(configuration.beforeLoad, element);
159
160                        // set source
161                        imageObj.attr("src", element.attr(configuration.attribute));
162
163                        // trigger function before loading image
164                        _triggerCallback(configuration.onLoad, element);
165                        onLoad = false;
166
167                        // call after load even on cached image
168                        if( imageObj.complete ) imageObj.load();
169
170                        // mark element always as loaded
171                        element.data("status", "loading");
172                    }
173                }
174            });
175
176            // cleanup all items which are already loaded
177            items = $(items).filter(function()
178            {
179                return $(this).data("status") !="loaded";
180            });
181        }
182
183        /**
184         * _init()
185         *
186         * initialize lazy plugin
187         * bind loading to events or set delay time to load all images at once
188         *
189         * @return void
190         */
191        function _init()
192        {
193            // if delay time is set load all images at once after delay time
194            if( configuration.delay >= 0 ) setTimeout(function() { lazyLoadImages(true); }, configuration.delay);
195
196            // if no delay is set or combine usage is active bind events
197            if( configuration.delay < 0 || configuration.combined )
198            {
199                // load initial images
200                lazyLoadImages(false);
201
202                // bind lazy load functions to scroll and resize event
203                $(configuration.appendScroll).bind("scroll", _throttle(configuration.throttle, lazyLoadImages));
204                $(configuration.appendScroll).bind("resize", _throttle(configuration.throttle, lazyLoadImages));
205            }
206        }
207
208        /**
209         * _isInLoadableArea(element)
210         *
211         * check if the given element is inside the current viewport or threshold
212         *
213         * @param element jQuery
214         * @return boolean
215         */
216        function _isInLoadableArea(element)
217        {
218            var top = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop;
219            //return (top + _getActualHeight() + configuration.threshold) > (element.offset().top + element.height());
220            return (top + _getActualHeight()) > (element.offset().top  + configuration.threshold);//change by steve
221        }
222
223        /**
224         * _getActualHeight()
225         *
226         * try to allocate current viewport height of the browser
227         * uses fallback option when no height is found
228         *
229         * @return number
230         */
231        function _getActualHeight()
232        {
233            if( window.innerHeight ) return window.innerHeight;
234            if( document.documentElement && document.documentElement.clientHeight ) return document.documentElement.clientHeight;
235            if( document.body && document.body.clientHeight ) return document.body.clientHeight;
236            if( document.body && document.body.offsetHeight ) return document.body.offsetHeight;
237
238            return configuration.fallbackHeight;
239        }
240
241        /**
242         * _throttle(delay, call)
243         *
244         * helper function to throttle down event triggering
245         *
246         * @param delay integer
247         * @param call function object
248         * @return function object
249         */
250        function _throttle(delay, call)
251        {
252            var _timeout;
253            var _exec = 0;
254
255            function callable()
256            {
257                var elapsed = +new Date() - _exec;
258
259                function run()
260                {
261                    _exec = +new Date();
262                    call.apply();
263                }
264
265                _timeout && clearTimeout(_timeout);
266
267                if( elapsed > delay || !configuration.enableThrottle ) run();
268                else _timeout = setTimeout(run, delay - elapsed);
269            }
270
271            return callable;
272        }
273
274        /**
275         * _reduceAwaiting()
276         *
277         * reduce count of awaiting elements to the afterLoad event and fire onFinishedAll if reached zero
278         *
279         * @return void
280         */
281        function _reduceAwaiting()
282        {
283            --awaitingAfterLoad;
284
285            // if no items were left trigger finished event 
286            if( !items.size() && !awaitingAfterLoad ) _triggerCallback(configuration.onFinishedAll, null);
287        }
288
289        /**
290         * _triggerCallback(callback, element)
291         *
292         * single implementation to handle callbacks and pass parameter
293         *
294         * @param callback function object
295         * @param element jQuery
296         * @return void
297         */
298        function _triggerCallback(callback, element)
299        {
300            if( callback )
301            {
302                if( element !== null )
303                    callback(element);
304                else
305                    callback();
306            }
307        }
308
309        return this;
310    };
311
312    // make lazy a bit more case-insensitive :)
313    $.fn.Lazy = $.fn.lazy;
314
315})(jQuery, window, document);

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.