PageSourceSearch

https://domel.ru/components/com_droppics/assets/js/jquery.esn.autobrowse.js

js domel.ru collected 2026-10-06 21:55:05 UTC 11,357 bytes, 268 lines download raw bytes

1/**
2 * Version 2.0
3 *
4 * Written by Micael Sjölund, ESN (http://www.esn.me)
5 * LICENCE: Do whatever you want with the code. I don't take any responsibility for how you use it.
6 *
7 * Creates a growing container that automatically fills its content via ajax requests, when the user scrolls to the
8 * bottom of the container. More info: http://pushingtheweb.com/2010/09/endless-scroller-jquery-plugin/
9 *
10 * Requires jStorage (), if the useCache option is set to true. WARNING: Somewhat experimental. See below for more info.
11 *
12 *
13 * Usage:
14 * .autobrowse(options)
15 *    options   Map of property-value options which controls plugin behaviour.
16 * .autobrowse(command)
17 *    command   String command that can be sent to the plugin.
18 *
19 *
20 * * COMMANDS
21 * * "flush"        Clears the plugin cache
22 *
23 *
24 * * OPTIONS
25 * * url            Callback to render url from offset argument.
26 *                  Example: function (offset) { return "http://mydomain.com/OFFSET/20".replace(/OFFSET/, offset) }
27 * * template       Callback to render markup from json response.
28 *                  Example: function (response) { var markup=''; for (var i=0; i<response.length; i++) { markup+='<img src="'+response[i]+'" />' } return markup; }
29 * * itemsReturned  Callback that is run on ajax json response to determine how many items was returned
30 *
31 * * OPTIONAL OPTIONS
32 * * loader         Element, jQuery object or markup to indicate to the user that the site is waiting for more items.
33 * * offset         Item offset for first ajax call to url, if you have already rendered items on the page
34 * * max            Maximum number of items to be retrieved by the plugin (can also be used to tell the plugin how many
35 *                  items there are in total on the server, so that no unneccesary requests are made.
36 * * complete       Callback that is run when the element has been updated with new content. This is run before the
37 *                  response is stored (if using useCache), making it is possible to manipulate the response here before
38 *                  it is stored.
39 * * sensitivity    Number of pixels before end of element that the plugin will start fetching more items.
40 * * postData       If you want to do a POST request instead of a GET request, supply this argument, either as a
41 *                  function or an object. If not set, a GET request will be made.
42 * * useCache       If true, the plugin will use browser storage to keep the state between page loads. If the user
43 *                  clicks away from the page and then goes back, all items fetched will be rendered again, and the
44 *                  user will see the same view as when he left the page. Requires http://www.jstorage.info/.
45 *                  WARNING: This doesn't work with original jStorage. A modified version is
46 *                  available on http://github.com/msjolund/jquery-esn-autobrowse. jStorage also
47 *                  requires jquery-json: http://code.google.com/p/jquery-json/. Default: false
48 * * expiration     How long to keep cache, in hours. Default: 24
49 * * stopFunction 	a function that will return true if it is necessary to stop autoscrolling
50 * * onError		a function that will be executed on error (HTTP response 500, etc.)
51 * * timeout        
52 */
53(function( $ ){
54jQuery.fn.autobrowse = function (options)
55{
56    var defaults = {
57        url: function (offset) { return "/"; },
58        template: function (response) { return ""; },
59        offset: 0,
60        max: null,
61        loader: '<div class="loader"></div>',
62        itemsReturned: function (response) { return response.length },
63        complete: function (response) {},
64        finished: function (response) {},
65        useCache: false,
66        expiration: 24,
67        sensitivity: 0,
68        postData: null,
69        stopFunction: function () {},
70        onError: function () {},
71        timeout: 500
72    };
73
74    // flush cache command
75    if (typeof options == "string" && options == "flush")
76    {
77        jQuery.jStorage.flush();
78        return this;
79    }
80
81    options = jQuery.extend(defaults, options);
82
83    // allow non-dynamic url
84    if (typeof options.url == "string")
85    {
86        var url = options.url;
87        options.url = function (offset) { return url; }
88    }else if(typeof options.url !== "function"){
89        options.url = false;
90    }
91
92    var getDataLength = function (data)
93    {
94        var length = 0;
95        for (var i = 0; i < data.length; i++)
96            length += options.itemsReturned(data[i]);
97        return length;
98    };
99
100    return this.each( function ()
101    {
102        var localData, obj = jQuery(this);
103        var currentOffset = options.offset;
104        var loading = false;
105        var scrollTopUpdateTimer = null;
106		var stopping = false;
107
108        var _stopPlugin = function (handler)
109        {
110            jQuery(window).unbind("scroll", handler);
111            options.finished.call(obj);
112        };
113
114        var scrollCallback = function ()
115        {
116            var scrollTop = jQuery(window).scrollTop();
117            var objBottom = obj.height() + obj.offset().top;
118            var winHeight = window.innerHeight ? window.innerHeight : $(window).height();
119            var winBtmPos = scrollTop + winHeight;
120            if (scrollTopUpdateTimer){
121                clearTimeout(scrollTopUpdateTimer);
122            }
123            if (options.useCache) {
124                    scrollTopUpdateTimer = setTimeout(function () { jQuery.jStorage.set("autobrowseScrollTop", scrollTop); }, 200);
125            }
126            if (objBottom  < winBtmPos + options.sensitivity && !loading)
127            {
128                loading = true;
129                if(typeof options.loader ==='string'){
130                    var loader = jQuery(options.loader);
131                    loader.appendTo(obj);
132                }else{
133                    var loader = options.loader;
134                    obj.append(loader.append());
135                }
136                
137                var ajaxCallback = function (response) {
138                    if (options.itemsReturned(response) > 0)
139                    {
140                        // Create the markup and append it to the container
141                        try { var markup = options.template(response); }
142                        catch (e) { console.error(e) } // ignore for now
143                        var newElements = jQuery(markup);
144                        newElements.appendTo(obj);
145
146                        // Call user onComplete callback
147                        options.complete.call(obj, response, newElements);
148
149                        // Store in local cache if option is set, and everything fetched fitted into the storage
150                        if (options.useCache && getDataLength(localData) + options.offset == currentOffset)
151                        {
152                            localData.push(response);
153                            if (!jQuery.jStorage.set("autobrowseStorage", localData))
154                                // Storage failed, remove last pushed response
155                                localData.pop();
156                        }
157
158                        // Update offsets
159                        currentOffset += options.itemsReturned(response);
160                        if (options.useCache)
161                        {
162                            jQuery.jStorage.set("autobrowseOffset", currentOffset);
163                        }
164                    }
165
166                    loader.remove();
167                    // Check if these were the last items to fetch from the server, if so, stop listening
168                    if (options.itemsReturned(response) == 0 || (options.max != null && currentOffset >= options.max) || options.stopFunction(response) === true)
169                    {
170                        _stopPlugin(scrollCallback);
171                        stopping = true;
172                    }                    
173                    if(options.url === false){
174                        window.setTimeout(function(){
175                            loading = false;
176                            if (!stopping) {
177                                    scrollCallback();
178                            }
179                        },options.timeout);
180                    }else{
181                        loading = false;
182                        if (!stopping) {
183                            scrollCallback();
184                        }
185                    }
186                };
187
188                if(options.url !== false){
189                    if (options.postData)
190                    {
191                        var data = null;
192                        if (typeof options.postData == "function")
193                        {
194                            data = options.postData();
195                        }
196                        else
197                        {
198                            data = options.postData;
199                        }
200
201                        jQuery.post(options.url(currentOffset), data, ajaxCallback, "json").error(options.onError);
202                    }
203                    else
204                    {
205                        jQuery.getJSON(options.url(currentOffset), ajaxCallback).error(options.onError);
206                    }
207                }else{
208                        ajaxCallback();
209                }
210            }
211        };
212
213        var _startPlugin = function()
214        {
215            if (options.useCache)
216                var autobrowseScrollTop = jQuery.jStorage.get("autobrowseScrollTop");
217            if (autobrowseScrollTop)
218                jQuery(window).scrollTop(autobrowseScrollTop);
219            jQuery(window).scroll(scrollCallback);
220            scrollCallback();
221        };
222
223
224        if (options.useCache)
225        {
226            if (jQuery.jStorage.get("autobrowseStorageKey") != options.url(0,0))
227            {
228                // flush cache if wrong page
229                jQuery.jStorage.flush();
230            }
231            else if (jQuery.jStorage.get("autobrowseExpiration") && jQuery.jStorage.get("autobrowseExpiration") < (new Date()).getTime())
232            {
233                // flush cache if it's expired
234                jQuery.jStorage.flush();
235            }
236            localData= jQuery.jStorage.get("autobrowseStorage");
237            if (localData)
238            {
239                // for each stored ajax response
240                for (var i = 0; i < localData.length; i++)
241                {
242                    var markup = options.template(localData[i]);
243                    jQuery(markup).appendTo(obj);
244                    currentOffset += options.itemsReturned(localData[i]);
245                    options.complete.call(obj, localData[i]);
246                }
247                _startPlugin();
248            }
249            else
250            {
251                localData = [];
252                jQuery.jStorage.get("autobrowseStorageKey")
253                jQuery.jStorage.set("autobrowseExpiration", (new Date()).getTime()+options.expiration*60*60*1000);
254                jQuery.jStorage.set("autobrowseOffset", currentOffset);
255                jQuery.jStorage.set("autobrowseStorageKey", options.url(0, 0));
256                jQuery.jStorage.set("autobrowseStorage", localData);
257                jQuery.jStorage.set("autobrowseScrollTop", 0);
258                _startPlugin();
259            }
260        }
261
262        else
263        {
264            _startPlugin();
265        }
266    });
267};
268})( jQuery );

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.