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.