Browse files

Handle scripts that tries to get src from lazyloaded images

Ex: Slideshow tries to get src using $('img').attr('src'), we will now
give him the real src if it exists (stored in lazyAttr, 'data-src').

This overrides HTMLImgElement.prototype.getAttribute (scary), does not
works for ie <8 (also this is a double ice cream).
  • Loading branch information...
1 parent 9347635 commit 17966dcd8ae2280e44882b5fb8b6edd7fcb46541 vvo committed Aug 27, 2012
Showing with 91 additions and 7 deletions.
  1. +19 −0 lazyload.js
  2. +6 −6 lazyload.min.js
  3. +1 −1 package.json
  4. +65 −0 test/getattribute.html
View
19 lazyload.js
@@ -44,6 +44,11 @@ if (!window['lzld']) {
saveViewportT = throttle(viewport, 20),
showImagesT = throttle(showImages, 20);
+ // Override image element .getAttribute globally so that we give the real src
+ // does not works for ie < 8: http://perfectionkills.com/whats-wrong-with-extending-the-dom/
+ // Internet Explorer 7 (and below) [...] does not expose global Node, Element, HTMLElement, HTMLParagraphElement
+ window['HTMLImageElement'] && overrideGetattribute();
+
// Called from every lazy <img> onload event
window['lzld'] = onDataSrcImgLoad;
@@ -244,6 +249,20 @@ if (!window['lzld']) {
addEvent(window, 'scroll', showImagesT);
}
+ function overrideGetattribute() {
+ var original = HTMLImageElement.prototype.getAttribute;
+ HTMLImageElement.prototype.getAttribute = function(name) {
+ if(name === 'src') {
+ var realSrc = original.call(this, lazyAttr);
+ return realSrc || original.call(this, name);
+ } else {
+ // our own lazyloader will go through theses lines
+ // because we use getAttribute(lazyAttr)
+ return original.call(this, name);
+ }
+ }
+ }
+
// https://github.com/jquery/sizzle/blob/3136f48b90e3edc84cbaaa6f6f7734ef03775a07/sizzle.js#L708
var contains = document.documentElement.compareDocumentPosition ?
function( a, b ) {
View
12 lazyload.min.js
@@ -1,6 +1,6 @@
-/*! lazyload v0.8.4 fasterize.com | github.com/fasterize/lazyload#licence */
-window.lzld||function(e,d){function l(){m=!0;g();setTimeout(g,25)}function n(a,b){var c=0;return function(){var d=+new Date;d-c<b||(c=d,a.apply(this,arguments))}}function h(a,b,c){a.attachEvent?a.attachEvent&&a.attachEvent("on"+b,c):a.addEventListener(b,c,!1)}function i(a,b,c){a.detachEvent?a.detachEvent&&a.detachEvent("on"+b,c):a.removeEventListener(b,c,!1)}function o(a,b){return p(d.documentElement,a)&&a.getBoundingClientRect().top<v+w?(a.onload=null,a.removeAttribute("onload"),a.onerror=null,a.removeAttribute("onerror"),
-a.src=a.getAttribute(j),a.removeAttribute(j),f[b]=null,!0):!1}function q(){return 0>d.documentElement.clientHeight?d.body&&0<=d.body.clientHeight?d.body.clientHeight:0>e.innerHeight?0:e.innerHeight:d.documentElement.clientHeight}function r(){var a,b,c=f.length,d=!0;for(a=0;a<c;a++)b=f[a],null!==b&&!o(b,a)&&(d=!1);d&&m&&(k=!0,i(e,"resize",s),i(e,"scroll",g),i(e,"load",l))}function t(){k=!1;h(e,"resize",s);h(e,"scroll",g)}function u(a,b,c){var d;if(b){if(Array.prototype.indexOf)return Array.prototype.indexOf.call(b,
-a,c);d=b.length;for(c=c?0>c?Math.max(0,d+c):c:0;c<d;c++)if(c in b&&b[c]===a)return c}return-1}var p,w=200,j="data-src",v=q(),f=[],m=!1,k=!1,s=n(q,20),g=n(r,20);e.lzld=function(a){-1===u(a,f)&&(k&&t(),o(a,f.push(a)-1))};(function(a){function b(c){"readystatechange"===c.type&&"complete"!==d.readyState||(i("load"===c.type?e:d,c.type,b),f||(f=!0,a()))}function c(){try{d.documentElement.doScroll("left")}catch(a){setTimeout(c,50);return}b("poll")}var f=!1,g=!0;if("complete"===d.readyState)a();else{if(d.createEventObject&&
-d.documentElement.doScroll){try{g=!e.frameElement}catch(j){}g&&c()}h(d,"DOMContentLoaded",b);h(d,"readystatechange",b);h(e,"load",b)}})(function(){var a,b,c,e=d.getElementsByTagName("img");b=0;for(c=e.length;b<c;b+=1)a=e[b],a.getAttribute(j)&&-1===u(a,f)&&f.push(a);r();setTimeout(g,25)});h(e,"load",l);t();p=d.documentElement.compareDocumentPosition?function(a,b){return!!(a.compareDocumentPosition(b)&16)}:d.documentElement.contains?function(a,b){return a!==b&&(a.contains?a.contains(b):!1)}:function(a,
-b){for(;b=b.parentNode;)if(b===a)return!0;return!1}}(this,document);
+/*! lazyload v0.8.5 fasterize.com | github.com/fasterize/lazyload#licence */
+window.lzld||function(e,d){function n(){o=!0;h();setTimeout(h,25)}function p(a,b){var c=0;return function(){var d=+new Date;d-c<b||(c=d,a.apply(this,arguments))}}function g(a,b,c){a.attachEvent?a.attachEvent&&a.attachEvent("on"+b,c):a.addEventListener(b,c,!1)}function j(a,b,c){a.detachEvent?a.detachEvent&&a.detachEvent("on"+b,c):a.removeEventListener(b,c,!1)}function q(a,b){return A(d.documentElement,a)&&a.getBoundingClientRect().top<B+C?(a.onload=null,a.removeAttribute("onload"),a.onerror=null,a.removeAttribute("onerror"),
+a.src=a.getAttribute(k),a.removeAttribute(k),f[b]=null,!0):!1}function r(){return 0<=d.documentElement.clientHeight?d.documentElement.clientHeight:d.body&&0<=d.body.clientHeight?d.body.clientHeight:0<=e.innerHeight?e.innerHeight:0}function s(){var a=f.length,b,c=!0;for(b=0;b<a;b++){var d=f[b];null!==d&&!q(d,b)&&(c=!1)}c&&o&&(l=!0,j(e,"resize",t),j(e,"scroll",h),j(e,"load",n))}function u(){l=!1;g(e,"resize",t);g(e,"scroll",h)}function v(a,b,c){var d;if(b){if(Array.prototype.indexOf)return Array.prototype.indexOf.call(b,
+a,c);d=b.length;for(c=c?0>c?Math.max(0,d+c):c:0;c<d;c++)if(c in b&&b[c]===a)return c}return-1}var C=200,k="data-src",B=r(),f=[],o=!1,l=!1,t=p(r,20),h=p(s,20);if(e.HTMLImageElement){var m=HTMLImageElement.prototype.getAttribute;HTMLImageElement.prototype.getAttribute=function(a){return"src"===a?m.call(this,k)||m.call(this,a):m.call(this,a)}}e.lzld=function(a){-1===v(a,f)&&(l&&u(),q(a,f.push(a)-1))};var w=function(){for(var a=d.getElementsByTagName("img"),b,c=0,e=a.length;c<e;c+=1)b=a[c],b.getAttribute(k)&&
+-1===v(b,f)&&f.push(b);s();setTimeout(h,25)},i=function(a){"readystatechange"===a.type&&"complete"!==d.readyState||(j("load"===a.type?e:d,a.type,i),x||(x=!0,w()))},y=function(){try{d.documentElement.doScroll("left")}catch(a){setTimeout(y,50);return}i("poll")},x=!1,z=!0;if("complete"===d.readyState)w();else{if(d.createEventObject&&d.documentElement.doScroll){try{z=!e.frameElement}catch(D){}z&&y()}g(d,"DOMContentLoaded",i);g(d,"readystatechange",i);g(e,"load",i)}g(e,"load",n);u();var A=d.documentElement.compareDocumentPosition?
+function(a,b){return!!(a.compareDocumentPosition(b)&16)}:d.documentElement.contains?function(a,b){return a!==b&&(a.contains?a.contains(b):!1)}:function(a,b){for(;b=b.parentNode;)if(b===a)return!0;return!1}}(this,document);
View
2 package.json
@@ -1,7 +1,7 @@
{
"name": "lazyload",
"description": "Image lazy loading",
- "version": "0.8.4",
+ "version": "0.8.5",
"repository": {
"type": "git",
"url": "http://github.com/fasterize/lazyload.git"
View
65 test/getattribute.html
@@ -0,0 +1,65 @@
+<!doctype html>
+<html>
+<head>
+ <title>getAttribute test</title>
+ <script src="../lazyload.js"></script>
+ <script src="./jquery-1.7.2.js"></script>
+ <style>html,body{margin:0;padding:0;background:#00f}</style>
+</head>
+<body>
+<script>
+ var srcs = [];
+
+ function done() {
+ var res = 'success';
+ for (var i = 0, max = srcs.length; i < max; i++) {
+ if (srcs[i].indexOf('imgs/1.jpg') === -1) {
+ res = 'error ('+srcs[i]+')';
+ break;
+ }
+ }
+
+ $('#result').text(res);
+ }
+
+ // domready
+ $(function() {
+ srcs.push(document.getElementsByTagName('img')[0].getAttribute('src'));
+ srcs.push(document.getElementById('img1').getAttribute('src'))
+ srcs.push($('#img2').attr('src'));
+ });
+
+ // onload
+ $(window).load(function() {
+ // fails in ie < 8
+ srcs.push($('#img4').attr('src'));
+ done();
+ });
+
+</script>
+
+<p>We checks that in any situation when a script requests an img src, we give real src, not
+ the fake blank image.</p>
+
+<p>A lot of slideshows are trying to get src attributes. Attention, we cannot handle img['src']</p>
+
+<p style="background: #fff">It passes if it says `success`: <span id="result"></span></p>
+
+<img id="img1" style="border:10px solid #000;display:block" width=200 height=200 data-src="imgs/1.jpg" src=data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== onload=lzld(this) onerror=lzld(this) />
+
+<img id="img2" style="border:10px solid #000;display:block" width=200 height=200 data-src="imgs/1.jpg" src=data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== onload=lzld(this) onerror=lzld(this) />
+
+<div style="height:900px"></div>
+
+<img id="img3" style="border:10px solid #000;display:block" width=200 height=200 data-src="imgs/1.jpg" src=data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== onload=lzld(this) onerror=lzld(this) />
+
+<img id="img4" style="border:10px solid #000;display:block" width=200 height=200 data-src="imgs/1.jpg" src=data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== onload=lzld(this) onerror=lzld(this) />
+
+<script>
+ // before dom ready
+ // fails in ie < 8
+ srcs.push(document.getElementById('img3').getAttribute('src'));
+</script>
+
+</body>
+</html>

0 comments on commit 17966dc

Please sign in to comment.