|
1 |
| -/*! Lazy Load XT v0.8.11 2014-01-10 |
| 1 | +/*! Lazy Load XT v0.8.12 2014-01-12 |
2 | 2 | * http://ressio.github.io/lazy-load-xt
|
3 | 3 | * (C) 2014 RESS.io
|
4 | 4 | * Licensed under MIT */
|
|
25 | 25 | edgeY: 0,
|
26 | 26 | visibleOnly: true
|
27 | 27 | },
|
28 |
| - // autoload all images in Opera Mini and some mobile browsers without scroll event |
29 |
| - autoLoad = (window.onscroll === undefined || !!window.operamini), |
30 | 28 | $window = $(window),
|
| 29 | + $isFunction = $.isFunction, |
| 30 | + docElement = document.documentElement, |
| 31 | + // autoload all images in Opera Mini and some mobile browsers without scroll event or getBoundingClientRect() |
| 32 | + autoLoad = (window.onscroll === undefined || !!window.operamini || !docElement.getBoundingClientRect), |
31 | 33 | dataLazied = 'lazied',
|
| 34 | + load_error = 'load error', |
32 | 35 | elements = [],
|
33 |
| - viewportTop, |
34 |
| - viewportBottom, |
35 |
| - viewportLeft, |
36 |
| - viewportRight, |
37 | 36 | $data = $.data || function (el, name) {
|
38 | 37 | return $(el).data(name);
|
39 | 38 | },
|
|
47 | 46 |
|
48 | 47 | $.lazyLoadXT = $.extend(options, elementOptions, $.lazyLoadXT);
|
49 | 48 |
|
| 49 | + /** |
| 50 | + * Return def if value is undefined, otherwise return value |
| 51 | + * @param {*} value |
| 52 | + * @param {*} def |
| 53 | + * @returns * |
| 54 | + */ |
| 55 | + function getOrDef(value, def) { |
| 56 | + return value === undefined ? def : value; |
| 57 | + } |
| 58 | + |
| 59 | + |
50 | 60 | /**
|
51 | 61 | * Add new elements to lazy-load list:
|
52 | 62 | * $(elements).lazyLoadXT() or $(window).lazyLoadXT()
|
|
57 | 67 | overrides = overrides || {};
|
58 | 68 |
|
59 | 69 | var elementOptionsOverrides = {},
|
60 |
| - blankImage = overrides.blankImage || options.blankImage, |
61 |
| - classNojs = overrides.classNojs || options.classNojs, |
62 |
| - checkDuplicates = overrides.checkDuplicates || true, |
| 70 | + blankImage = getOrDef(overrides.blankImage, options.blankImage), |
| 71 | + classNojs = getOrDef(overrides.classNojs, options.classNojs), |
| 72 | + checkDuplicates = getOrDef(overrides.checkDuplicates, true), |
63 | 73 | prop;
|
64 | 74 |
|
65 | 75 | for (prop in elementOptions) {
|
66 |
| - elementOptionsOverrides[prop] = (overrides[prop] === undefined) ? options[prop] : overrides[prop]; |
| 76 | + elementOptionsOverrides[prop] = getOrDef(overrides[prop], options[prop]); |
67 | 77 | }
|
68 | 78 |
|
69 | 79 | return this.each(function () {
|
|
81 | 91 | .data(dataLazied, 1)
|
82 | 92 | .removeClass(classNojs);
|
83 | 93 |
|
84 |
| - if (blankImage && $el[0].tagName === 'IMG' && !$el.attr('src')) { |
85 |
| - $el.attr('src', blankImage); |
| 94 | + if (blankImage && $el[0].tagName === 'IMG' && !this.src) { |
| 95 | + this.src = blankImage; |
86 | 96 | }
|
87 | 97 |
|
88 | 98 | // clone elementOptionsOverrides object
|
|
96 | 106 | };
|
97 | 107 |
|
98 | 108 |
|
99 |
| - /** |
100 |
| - * Save visible viewport boundary to viewportXXX variables |
101 |
| - */ |
102 |
| - function calcViewport() { |
103 |
| - viewportTop = $window.scrollTop(); |
104 |
| - viewportBottom = viewportTop + (window.innerHeight || $window.height()); |
105 |
| - |
106 |
| - viewportLeft = window.pageXOffset || 0; |
107 |
| - viewportRight = viewportLeft + (window.innerWidth || $window.width()); |
108 |
| - } |
109 |
| - |
110 |
| - |
111 | 109 | /**
|
112 | 110 | * Process function/object event handler
|
113 | 111 | * @param {string} event suffix
|
|
118 | 116 |
|
119 | 117 | var handler = options['on' + event];
|
120 | 118 | if (handler) {
|
121 |
| - if ($.isFunction(handler)) { |
| 119 | + if ($isFunction(handler)) { |
122 | 120 | handler.call($el[0]);
|
123 | 121 | } else {
|
124 | 122 | $el
|
|
137 | 135 | * @param {Event} e
|
138 | 136 | */
|
139 | 137 | function triggerLoadOrError(e) {
|
140 |
| - triggerEvent(e.type, $(this).off('load error', triggerLoadOrError)); |
| 138 | + triggerEvent(e.type, $(this).off(load_error, triggerLoadOrError)); |
141 | 139 | }
|
142 | 140 |
|
143 | 141 |
|
|
153 | 151 | force = force || autoLoad;
|
154 | 152 |
|
155 | 153 | topLazy = Infinity;
|
156 |
| - calcViewport(); |
157 | 154 |
|
158 |
| - for (var i = elements.length - 1; i >= 0; i--) { |
| 155 | + var viewportTop = $window.scrollTop(), |
| 156 | + viewportHeight = window.innerHeight || $window.height(), |
| 157 | + viewportWidth = window.innerWidth || $window.width(), |
| 158 | + i; |
| 159 | + |
| 160 | + for (i = elements.length - 1; i >= 0; i--) { |
159 | 161 | var $el = elements[i],
|
160 | 162 | el = $el[0],
|
161 | 163 | objData = $el.lazyLoadXT;
|
162 | 164 |
|
163 | 165 | // remove items that are not in DOM
|
164 |
| - if (!$.contains(document.documentElement, el)) { |
| 166 | + if (!$.contains(docElement, el)) { |
165 | 167 | elements.splice(i, 1);
|
166 | 168 | } else if (force || !objData.visibleOnly || el.offsetWidth > 0 || el.offsetHeight > 0) {
|
167 |
| - var offset = $el.offset(), |
168 |
| - elTop = offset.top, |
169 |
| - elLeft = offset.left, |
| 169 | + var elPos = el.getBoundingClientRect(), |
170 | 170 | edgeX = objData.edgeX,
|
171 | 171 | edgeY = objData.edgeY,
|
172 |
| - topEdge = elTop - edgeY; |
| 172 | + topEdge = (elPos.top + viewportTop - edgeY) - viewportHeight; |
173 | 173 |
|
174 |
| - if (force || |
175 |
| - ((topEdge <= viewportBottom) && (elTop + $el.height() > viewportTop - edgeY) && |
176 |
| - (elLeft <= viewportRight + edgeX) && (elLeft + $el.width() > viewportLeft - edgeX))) { |
| 174 | + if (force || (topEdge <= viewportTop && elPos.bottom > -edgeY && |
| 175 | + elPos.left <= viewportWidth + edgeX && elPos.right > -edgeX)) { |
177 | 176 |
|
178 | 177 | triggerEvent('show', $el);
|
179 | 178 |
|
180 | 179 | var srcAttr = objData.srcAttr,
|
181 |
| - src = $.isFunction(srcAttr) ? srcAttr($el) : $el.attr(srcAttr); |
| 180 | + src = $isFunction(srcAttr) ? srcAttr($el) : el.getAttribute(srcAttr); |
182 | 181 | if (src) {
|
183 |
| - $el |
184 |
| - .on('load error', triggerLoadOrError) |
185 |
| - .attr('src', src); |
| 182 | + $el.on(load_error, triggerLoadOrError); |
| 183 | + el.src = src; |
186 | 184 | }
|
187 | 185 |
|
188 | 186 | elements.splice(i, 1);
|
|
225 | 223 |
|
226 | 224 | // fast check for scroll event without new visible elements
|
227 | 225 | if (e && e.type === 'scroll') {
|
228 |
| - calcViewport(); |
229 |
| - if (topLazy >= viewportBottom) { |
| 226 | + if (topLazy >= $window.scrollTop()) { |
230 | 227 | return;
|
231 | 228 | }
|
232 | 229 | }
|
|
0 commit comments