PageSourceSearch

https://hqdenver.com/assets/global/js/lazyload.js

js hqdenver.com collected 2026-10-08 12:02:17 UTC 9,546 bytes, 327 lines download raw bytes

1/**
2 * @preserve LaziestLoader - v0.7.3 - 2016-01-03
3 * A responsive lazy loader for jQuery.
4 * http://sjwilliams.github.io/laziestloader/
5 * Copyright (c) 2016 Josh Williams; Licensed MIT
6 */
7
8 (function(factory) {
9  if (typeof define === 'function' && define.amd) {
10    define(['jquery'], factory);
11  } else {
12    factory(jQuery);
13  }
14}(function($) {
15
16  var laziestLoader = function(options, callback) {
17
18    var $w = $(window),
19      $elements = this,
20      $loaded = $(), // elements with the correct source set
21      retina = window.devicePixelRatio > 1,
22      didScroll = false;
23
24    options = $.extend(true, {
25      threshold: 0,
26      sizePattern: /{{SIZE}}/ig,
27      getSource: getSource,
28      event: 'scroll',
29      scrollThrottle: 250, // time in ms to throttle scroll. Increase for better performance.
30      sizeOffsetPercent: 0, // Subtract this % of width from the containing element, and fit images as though the element were that size. 0 = fit to element size; 40 = size - 40%; -30 = size + 30%
31      setSourceMode: true // plugin sets source attribute of the element. Set to false if you would like to, instead, use the callback to completely manage the element on trigger.
32    }, options);
33
34
35    var useNativeScroll = (typeof options.event === 'string') && (options.event.indexOf('scroll') === 0);
36
37    /**
38     * Generate source path of image to load. Take into account
39     * type of data supplied and whether or not a retina
40     * image is available.
41     *
42     * Basic option: data attributes specifing a single image to load,
43     * regardless of viewport.
44     * Eg:
45     *
46     * <img data-src="yourimage.jpg">
47     * <img data-src="yourimage.jpg" data-src-retina="yourretinaimage.jpg">
48     *
49     * Range of sizes: specify a string path with a {{size}} that
50     * will be replaced by an integer from a list of available sizes.
51     * Eg:
52     *
53     * <img data-pattern="path/toyourimage-{{size}}.jpg" data-widths="[320, 640, 970]">
54     * <img data-pattern="path/toyourimage-{{size}}.jpg" data-pattern-retina="path/toyourimage-{{size}}@2x.jpg" data-widths="[320, 640, 970]">
55     * <img data-pattern="path/toyourimage/{{size}}/slug.jpg" data-pattern-retina="path/toyourimage/{{size}}/[email protected]" data-widths="[320, 640, 970]">
56     *
57     * Range of sizes, with slugs: specify a string path with a {{size}} that
58     * will be replaced by a slug representing an image size.
59     * Eg:
60     *
61     * <img data-pattern="path/toyourimage-{{size}}.jpg" data-widths="[{width: 320, slug: 'small'},{width:900, slug: 'large'}]">
62     *
63     * @param  {jQuery object} $el
64     * @return {String}
65     */
66
67    function getSource($el) {
68      var source, slug;
69      var data = $el.data();
70      if (data.pattern && data.widths && $.isArray(data.widths)) {
71        source = retina ? data.patternRetina : data.pattern;
72        source = source || data.pattern;
73
74        // width or slug version?
75        if (typeof data.widths[0] === 'object') {
76          slug = (function() {
77            var widths = $.map(data.widths, function(val) {
78              return val.size;
79            });
80
81            var bestFitWidth = bestFit($el.width(), widths);
82
83            // match best width back to its corresponding slug
84            for (var i = data.widths.length - 1; i >= 0; i--) {
85              if (data.widths[i].size === bestFitWidth) {
86                return data.widths[i].slug;
87              }
88            }
89          })();
90
91          source = source.replace(options.sizePattern, slug);
92        } else {
93          source = source.replace(options.sizePattern, bestFit($el.width(), data.widths));
94        }
95      } else {
96        source = retina ? data.srcRetina : data.src;
97        source = source || data.src;
98      }
99
100      return source;
101    }
102
103    /**
104     * Reflect loaded state in class names
105     * and fire event.
106     *
107     * @param  {jQuery Object} $el
108     */
109    function onLoad($el) {
110      $el.addClass('ll-loaded').removeClass('ll-notloaded');
111      $el.trigger('loaded');
112
113      if (typeof callback === 'function') {
114        callback.call($el);
115      }
116    }
117
118    /**
119     * Attach event handler that sets correct
120     * media source for the elements' width, or
121     * allows callback to manipulate element
122     * exclusively.
123     */
124
125    function bindLoader() {
126      $elements.one('laziestloader', function() {
127        var $el = $(this);
128        var source;
129
130        // set height?
131        if ($el.data().ratio) {
132          setHeight.call(this);
133        }
134
135        // set content. default: set element source
136        if (options.setSourceMode) {
137          source = options.getSource($el);
138          if (source && this.getAttribute('src') !== source) {
139            this.setAttribute('src', source);
140          }
141        }
142
143        // applied immediately to reflect that media has started but,
144        // perhaps, hasn't finished downloading.
145        $el.addClass('ll-loadstarted');
146
147        // Determine when to fire `loaded` event. Wait until
148        // media is truly loaded if possible, otherwise immediately.
149        if (options.setSourceMode && (this.nodeName === 'IMG' || this.nodeName === 'VIDEO' || this.nodeName === 'AUDIO') ) {
150          if (this.nodeName === 'IMG') {
151            this.onload = function() {
152              onLoad($el);
153            };
154          } else {
155            this.onloadstart = function() {
156              onLoad($el);
157            };
158          }
159        } else {
160          onLoad($el);
161        }
162      });
163    }
164
165    /**
166     * Remove even handler from elements
167     */
168
169    function unbindLoader() {
170      $elements.off('laziestloader');
171    }
172
173    /**
174     * Find the best sized image, opting for larger over smaller
175     *
176     * @param  {Number} targetWidth   element width
177     * @param  {Array} widths         array of numbers
178     * @return {Number}
179     */
180
181    var bestFit = laziestLoader.bestFit = function(targetWidth, widths) {
182      var selectedWidth = widths[widths.length - 1],
183        i = widths.length,
184        offset = targetWidth * (options.sizeOffsetPercent / 100);
185
186      // sort smallest to largest
187      widths.sort(function(a, b) {
188        return a - b;
189      });
190
191      while (i--) {
192        if ((targetWidth - offset) <= widths[i]) {
193          selectedWidth = widths[i];
194        }
195      }
196
197      return selectedWidth;
198    };
199
200    /**
201     * Cycle through elements that haven't had their
202     * source set and, if they're in the viewport within
203     * the threshold, load their media
204     */
205
206    function laziestloader() {
207      var docEl = document.documentElement;
208      var wHeight = window.innerHeight || docEl.clientHeight;
209      var wWidth = window.innerWidth || docEl.clientWidth;
210      var threshold = options.threshold;
211
212      var $inview = $elements.not($loaded).filter(function() {
213        if ($(this).is(':hidden')) return;
214        var rect = $(this)[0].getBoundingClientRect();
215
216        return (
217          rect.bottom + threshold > 0 &&
218          rect.right + threshold > 0 &&
219          rect.left < wWidth + threshold &&
220          rect.top < wHeight + threshold
221        );
222      });
223
224      $inview.trigger('laziestloader');
225      $loaded.add($inview);
226    }
227
228
229    /**
230     * Given a lazy element, check if it should have
231     * its height set based on a data-ratio multiplier.
232     */
233    function setHeight() {
234      var $el = $(this),
235        data = $el.data();
236
237      data.ratio = data.ratio || data.heightMultiplier; // backwards compatible for old data-height-multiplier code.
238
239      if (data.ratio) {
240        $el.css({
241          height: Math.round($el.width() * data.ratio)
242        });
243      }
244    }
245
246    // add inital state classes, and check if
247    // element dimensions need to be set.
248    $elements.addClass('ll-init ll-notloaded').each(setHeight);
249
250    // initial binding
251    bindLoader();
252
253
254    // Watch either native scroll events, throttled by
255    // options.scrollThrottle, or a custom event that
256    // implements its own throttling.
257
258    if (useNativeScroll) {
259      $w.scroll(function(){
260        didScroll = true;
261      });
262
263      setInterval(function() {
264        if (didScroll) {
265          didScroll = false;
266          laziestloader();
267        }
268      }, options.scrollThrottle);
269
270    } else {
271
272      // if custom event is a function, it'll need
273      // to call laziestloader() manually, like so:
274      //
275      //   $('.g-lazy').laziestloader({
276      //    event: function(cb){
277      //      // custom scroll event on nytimes.com
278      //      PageManager.on('nyt:page-scroll', function(){
279      //       // do something interesting if you like
280      //       // and then call the passed in laziestloader();
281      //       cb();
282      //     });
283      //    }
284      //  });
285      //
286      //
287      // Otherwise, it's a string representing an event on the
288      // window to subscribe to, like so:
289      //
290      // // some code dispatching throttled events
291      // $window.trigger('nytg-scroll');
292      //
293      // $('.g-lazy').laziestloader({
294      //   event: 'nytg-scroll'
295      // });
296      //
297
298      if (typeof options.event === 'function') {
299        options.event(laziestloader);
300      } else {
301        $w.on(options.event, function(){
302          laziestloader();
303        });
304      }
305    }
306
307
308
309    // reset state on resize
310    $w.resize(function() {
311      $loaded = $();
312      unbindLoader();
313      bindLoader();
314      laziestloader();
315    });
316
317    // initial check for lazy images
318    $(document).ready(function() {
319      laziestloader();
320    });
321
322    return this;
323  };
324
325  $.fn.laziestloader = laziestLoader;
326
327}));

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.