├── demo ├── 1.jpg ├── 2.jpg ├── 3.jpg ├── 4.jpg ├── 5.jpg ├── blank.gif └── mobile │ ├── 1.jpg │ ├── 2.jpg │ ├── 3.jpg │ ├── 4.jpg │ └── 5.jpg ├── gh-page ├── fauxconsole.css ├── scale.fix.js ├── fauxconsole.js ├── pygment_trac.css └── styles.css ├── README.md ├── javascripts ├── lazyload.min.js └── lazyload.js └── index.html /demo/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaizau/Lazy-Load-Images-without-jQuery/HEAD/demo/1.jpg -------------------------------------------------------------------------------- /demo/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaizau/Lazy-Load-Images-without-jQuery/HEAD/demo/2.jpg -------------------------------------------------------------------------------- /demo/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaizau/Lazy-Load-Images-without-jQuery/HEAD/demo/3.jpg -------------------------------------------------------------------------------- /demo/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaizau/Lazy-Load-Images-without-jQuery/HEAD/demo/4.jpg -------------------------------------------------------------------------------- /demo/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaizau/Lazy-Load-Images-without-jQuery/HEAD/demo/5.jpg -------------------------------------------------------------------------------- /demo/blank.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaizau/Lazy-Load-Images-without-jQuery/HEAD/demo/blank.gif -------------------------------------------------------------------------------- /demo/mobile/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaizau/Lazy-Load-Images-without-jQuery/HEAD/demo/mobile/1.jpg -------------------------------------------------------------------------------- /demo/mobile/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaizau/Lazy-Load-Images-without-jQuery/HEAD/demo/mobile/2.jpg -------------------------------------------------------------------------------- /demo/mobile/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaizau/Lazy-Load-Images-without-jQuery/HEAD/demo/mobile/3.jpg -------------------------------------------------------------------------------- /demo/mobile/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaizau/Lazy-Load-Images-without-jQuery/HEAD/demo/mobile/4.jpg -------------------------------------------------------------------------------- /demo/mobile/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaizau/Lazy-Load-Images-without-jQuery/HEAD/demo/mobile/5.jpg -------------------------------------------------------------------------------- /gh-page/fauxconsole.css: -------------------------------------------------------------------------------- 1 | #fauxconsole{ 2 | position:absolute; 3 | top:0; 4 | right:0; 5 | width:300px; 6 | border:1px solid #999; 7 | font-family:courier,monospace; 8 | background:#eee; 9 | font-size:10px; 10 | padding:10px; 11 | } 12 | html>body #fauxconsole{ 13 | position:fixed; 14 | } 15 | #fauxconsole a{ 16 | float:right; 17 | padding-left:1em; 18 | padding-bottom:.5em; 19 | text-align:right; 20 | } 21 | -------------------------------------------------------------------------------- /gh-page/scale.fix.js: -------------------------------------------------------------------------------- 1 | var metas = document.getElementsByTagName('meta'); 2 | var i; 3 | if (navigator.userAgent.match(/iPhone/i)) { 4 | for (i=0; i'+o;console.show();},clear:function(){console.d.parentNode.removeChild(console.d);console.init();console.show();},/*Simon Willison rules*/addLoadEvent:function(func){var oldonload=window.onload;if(typeof window.onload!='function'){window.onload=func;}else{window.onload=function(){if(oldonload){oldonload();}func();}};}};console.addLoadEvent(console.init);} -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # About 2 | 3 | Lazy load your images without the overhead of a framework. Optionally, send mobile-optimized images to smaller screens. Tested on IE7+, Firefox, Chrome, Safari, iOS. 4 | 5 | Based on code from [Mike Pulaski](http://www.mikepulaski.com/code/2012/06/29/lazy-load-images-without-external-libraries/). 6 | 7 | # Usage 8 | 9 | 1) Include `lazyload.min.js` or inline it. 10 | 11 | 2) Add `.lazy-load` and `data-src` to each of your `` tags. Optionally add `data-src-mobile`, a placeholder src, and a fallback image. 12 | 13 | ```html 14 | 15 | 16 | ``` 17 | 18 | 3) Add CSS3 magic for an animated fade-in: 19 | 20 | ```css 21 | .lazy-load, .lazy-loaded { 22 | -webkit-transition: opacity 0.3s; 23 | -moz-transition: opacity 0.3s; 24 | -ms-transition: opacity 0.3s; 25 | -o-transition: opacity 0.3s; 26 | transition: opacity 0.3s; 27 | opacity: 0; 28 | } 29 | 30 | .lazy-loaded { opacity: 1; } 31 | ``` 32 | 33 | # Demo 34 | 35 | http://kaizau.github.com/Lazy-Load-Images-without-jQuery/ 36 | -------------------------------------------------------------------------------- /javascripts/lazyload.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Lazy Load Images without jQuery 3 | * http://kaizau.github.com/Lazy-Load-Images-without-jQuery/ 4 | * 5 | * Original by Mike Pulaski - http://www.mikepulaski.com 6 | * Modified by Kai Zau - http://kaizau.com 7 | */ 8 | !function(){function d(a){var b=0;if(a.offsetParent){do b+=a.offsetTop;while(a=a.offsetParent);return b}}var a=window.addEventListener||function(a,b){window.attachEvent("on"+a,b)},b=window.removeEventListener||function(a,b){window.detachEvent("on"+a,b)},c={cache:[],mobileScreenSize:500,addObservers:function(){a("scroll",c.throttledLoad),a("resize",c.throttledLoad)},removeObservers:function(){b("scroll",c.throttledLoad,!1),b("resize",c.throttledLoad,!1)},throttleTimer:(new Date).getTime(),throttledLoad:function(){var a=(new Date).getTime();a-c.throttleTimer>=200&&(c.throttleTimer=a,c.loadVisibleImages())},loadVisibleImages:function(){for(var a=window.pageYOffset||document.documentElement.scrollTop,b=window.innerHeight||document.documentElement.clientHeight,e={min:a-200,max:a+b+200},f=0;f=e.min-i&&h<=e.max){var j=g.getAttribute("data-src-mobile");g.onload=function(){this.className=this.className.replace(/(^|\s+)lazy-load(\s+|$)/,"$1lazy-loaded$2")},g.src=j&&screen.width<=c.mobileScreenSize?j:g.getAttribute("data-src"),g.removeAttribute("data-src"),g.removeAttribute("data-src-mobile"),c.cache.splice(f,1)}else f++}0===c.cache.length&&c.removeObservers()},init:function(){document.querySelectorAll||(document.querySelectorAll=function(a){var b=document,c=b.documentElement.firstChild,d=b.createElement("STYLE");return c.appendChild(d),b.__qsaels=[],d.styleSheet.cssText=a+"{x:expression(document.__qsaels.push(this))}",window.scrollBy(0,0),b.__qsaels}),a("load",function d(){for(var a=document.querySelectorAll("img[data-src]"),e=0;e= 200) { 32 | lazyLoader.throttleTimer = now; 33 | lazyLoader.loadVisibleImages(); 34 | } 35 | }, 36 | 37 | loadVisibleImages: function() { 38 | var scrollY = window.pageYOffset || document.documentElement.scrollTop; 39 | var pageHeight = window.innerHeight || document.documentElement.clientHeight; 40 | var range = { 41 | min: scrollY - 200, 42 | max: scrollY + pageHeight + 200 43 | }; 44 | 45 | var i = 0; 46 | while (i < lazyLoader.cache.length) { 47 | var image = lazyLoader.cache[i]; 48 | var imagePosition = getOffsetTop(image); 49 | var imageHeight = image.height || 0; 50 | 51 | if ((imagePosition >= range.min - imageHeight) && (imagePosition <= range.max)) { 52 | var mobileSrc = image.getAttribute('data-src-mobile'); 53 | 54 | image.onload = function() { 55 | this.className = this.className.replace(/(^|\s+)lazy-load(\s+|$)/, '$1lazy-loaded$2'); 56 | }; 57 | 58 | if (mobileSrc && screen.width <= lazyLoader.mobileScreenSize) { 59 | image.src = mobileSrc; 60 | } 61 | else { 62 | image.src = image.getAttribute('data-src'); 63 | } 64 | 65 | image.removeAttribute('data-src'); 66 | image.removeAttribute('data-src-mobile'); 67 | 68 | lazyLoader.cache.splice(i, 1); 69 | continue; 70 | } 71 | 72 | i++; 73 | } 74 | 75 | if (lazyLoader.cache.length === 0) { 76 | lazyLoader.removeObservers(); 77 | } 78 | }, 79 | 80 | init: function() { 81 | // Patch IE7- (querySelectorAll) 82 | if (!document.querySelectorAll) { 83 | document.querySelectorAll = function(selector) { 84 | var doc = document, 85 | head = doc.documentElement.firstChild, 86 | styleTag = doc.createElement('STYLE'); 87 | head.appendChild(styleTag); 88 | doc.__qsaels = []; 89 | styleTag.styleSheet.cssText = selector + "{x:expression(document.__qsaels.push(this))}"; 90 | window.scrollBy(0, 0); 91 | return doc.__qsaels; 92 | } 93 | } 94 | 95 | addEventListener('load', function _lazyLoaderInit() { 96 | var imageNodes = document.querySelectorAll('img[data-src]'); 97 | 98 | for (var i = 0; i < imageNodes.length; i++) { 99 | var imageNode = imageNodes[i]; 100 | 101 | // Add a placeholder if one doesn't exist 102 | //imageNode.src = imageNode.src || lazyLoader.tinyGif; 103 | 104 | lazyLoader.cache.push(imageNode); 105 | } 106 | 107 | lazyLoader.addObservers(); 108 | lazyLoader.loadVisibleImages(); 109 | 110 | removeEventListener('load', _lazyLoaderInit, false); 111 | }); 112 | } 113 | } 114 | 115 | // For IE7 compatibility 116 | // Adapted from http://www.quirksmode.org/js/findpos.html 117 | function getOffsetTop(el) { 118 | var val = 0; 119 | if (el.offsetParent) { 120 | do { 121 | val += el.offsetTop; 122 | } while (el = el.offsetParent); 123 | return val; 124 | } 125 | } 126 | 127 | lazyLoader.init(); 128 | })(); 129 | -------------------------------------------------------------------------------- /gh-page/styles.css: -------------------------------------------------------------------------------- 1 | @import url(https://fonts.googleapis.com/css?family=Lato:300italic,700italic,300,700); 2 | 3 | body { 4 | padding:50px; 5 | font:14px/1.5 Lato, "Helvetica Neue", Helvetica, Arial, sans-serif; 6 | color:#777; 7 | font-weight:300; 8 | } 9 | 10 | h1, h2, h3, h4, h5, h6 { 11 | color:#222; 12 | margin:0 0 20px; 13 | } 14 | 15 | p, ul, ol, table, pre, dl { 16 | margin:0 0 20px; 17 | } 18 | 19 | h1, h2, h3 { 20 | line-height:1.1; 21 | } 22 | 23 | h1 { 24 | font-size:28px; 25 | } 26 | 27 | h2 { 28 | color:#393939; 29 | } 30 | 31 | h3, h4, h5, h6 { 32 | color:#494949; 33 | } 34 | 35 | a { 36 | color:#39c; 37 | font-weight:400; 38 | text-decoration:none; 39 | } 40 | 41 | a small { 42 | font-size:11px; 43 | color:#777; 44 | margin-top:-0.6em; 45 | display:block; 46 | } 47 | 48 | .wrapper { 49 | width:860px; 50 | margin:0 auto; 51 | } 52 | 53 | blockquote { 54 | border-left:1px solid #e5e5e5; 55 | margin:0; 56 | padding:0 0 0 20px; 57 | font-style:italic; 58 | } 59 | 60 | code, pre { 61 | font-family:Monaco, Bitstream Vera Sans Mono, Lucida Console, Terminal; 62 | color:#333; 63 | font-size:12px; 64 | } 65 | 66 | pre { 67 | padding:8px 15px; 68 | background: #f8f8f8; 69 | border-radius:5px; 70 | border:1px solid #e5e5e5; 71 | overflow-x: auto; 72 | } 73 | 74 | table { 75 | width:100%; 76 | border-collapse:collapse; 77 | } 78 | 79 | th, td { 80 | text-align:left; 81 | padding:5px 10px; 82 | border-bottom:1px solid #e5e5e5; 83 | } 84 | 85 | dt { 86 | color:#444; 87 | font-weight:700; 88 | } 89 | 90 | th { 91 | color:#444; 92 | } 93 | 94 | img { 95 | max-width:100%; 96 | } 97 | 98 | header { 99 | width:270px; 100 | float:left; 101 | position:fixed; 102 | } 103 | 104 | header ul { 105 | list-style:none; 106 | height:40px; 107 | 108 | padding:0; 109 | 110 | background: #eee; 111 | background: -moz-linear-gradient(top, #f8f8f8 0%, #dddddd 100%); 112 | background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(100%,#dddddd)); 113 | background: -webkit-linear-gradient(top, #f8f8f8 0%,#dddddd 100%); 114 | background: -o-linear-gradient(top, #f8f8f8 0%,#dddddd 100%); 115 | background: -ms-linear-gradient(top, #f8f8f8 0%,#dddddd 100%); 116 | background: linear-gradient(top, #f8f8f8 0%,#dddddd 100%); 117 | 118 | border-radius:5px; 119 | border:1px solid #d2d2d2; 120 | box-shadow:inset #fff 0 1px 0, inset rgba(0,0,0,0.03) 0 -1px 0; 121 | width:270px; 122 | } 123 | 124 | header li { 125 | width:89px; 126 | float:left; 127 | border-right:1px solid #d2d2d2; 128 | height:40px; 129 | } 130 | 131 | header ul a { 132 | line-height:1; 133 | font-size:11px; 134 | color:#999; 135 | display:block; 136 | text-align:center; 137 | padding-top:6px; 138 | height:40px; 139 | } 140 | 141 | strong { 142 | color:#222; 143 | font-weight:700; 144 | } 145 | 146 | header ul li + li { 147 | width:88px; 148 | border-left:1px solid #fff; 149 | } 150 | 151 | header ul li + li + li { 152 | border-right:none; 153 | width:89px; 154 | } 155 | 156 | header ul a strong { 157 | font-size:14px; 158 | display:block; 159 | color:#222; 160 | } 161 | 162 | section { 163 | width:500px; 164 | float:right; 165 | padding-bottom:50px; 166 | } 167 | 168 | small { 169 | font-size:11px; 170 | } 171 | 172 | hr { 173 | border:0; 174 | background:#e5e5e5; 175 | height:1px; 176 | margin:0 0 20px; 177 | } 178 | 179 | footer { 180 | width:270px; 181 | float:left; 182 | position:fixed; 183 | bottom:50px; 184 | } 185 | 186 | @media print, screen and (max-width: 960px) { 187 | 188 | div.wrapper { 189 | width:auto; 190 | margin:0; 191 | } 192 | 193 | header, section, footer { 194 | float:none; 195 | position:static; 196 | width:auto; 197 | } 198 | 199 | header { 200 | padding-right:320px; 201 | } 202 | 203 | section { 204 | border:1px solid #e5e5e5; 205 | border-width:1px 0; 206 | padding:20px 0; 207 | margin:0 0 20px; 208 | } 209 | 210 | header a small { 211 | display:inline; 212 | } 213 | 214 | header ul { 215 | position:absolute; 216 | right:50px; 217 | top:52px; 218 | } 219 | } 220 | 221 | @media print, screen and (max-width: 720px) { 222 | body { 223 | word-wrap:break-word; 224 | } 225 | 226 | header { 227 | padding:0; 228 | } 229 | 230 | header ul, header p.view { 231 | position:static; 232 | } 233 | 234 | pre, code { 235 | word-wrap:normal; 236 | } 237 | } 238 | 239 | @media print, screen and (max-width: 480px) { 240 | body { 241 | padding:15px; 242 | } 243 | 244 | header ul { 245 | display:none; 246 | } 247 | } 248 | 249 | @media print { 250 | body { 251 | padding:0.4in; 252 | font-size:12pt; 253 | color:#444; 254 | } 255 | } 256 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Lazy load images without jQuery. by kaizau 9 | 10 | 11 | 12 | 13 | 16 | 17 | 31 | 32 | 35 | 36 | 37 | 38 |
39 |
40 |

Lazy load images without jQuery.

41 |

A totally lame name for a totally useful script.

42 | 43 |

View the Project on GitHub kaizau/Lazy-Load-Images-without-jQuery

44 | 45 | 50 |
51 |
52 | 53 |

About

54 |

Lazy load your images without the overhead of a framework. Optionally, send mobile-optimized images to smaller screens. Tested on IE7+, Firefox, Chrome, iOS.

55 | 56 |

Based on code from Mike Pulaski.

57 | 58 |

Usage

59 | 60 |
    61 |
  1. Include lazyload.min.js or inline it.

  2. 62 |
  3. 63 |

    Add .lazy-load and data-src to each of your <img> tags. Optionally add data-src-mobile, a placeholder src, and a fallback image.

    64 |
    65 |
    <img class="lazy-load" data-src="lazy.jpg" data-src-mobile="lazy-small.jpg" src="blank.gif" />
     66 | <noscript><img src="lazy.jpg" /></noscript>
     67 | 
    68 |
    69 |
  4. 70 |
  5. 71 |

    Add CSS3 for an animated fade-in.

    72 |
    73 |
    .lazy-load, .lazy-loaded {
     74 |   -webkit-transition: opacity 0.3s;
     75 |   -moz-transition: opacity 0.3s;
     76 |   -ms-transition: opacity 0.3s;
     77 |   -o-transition: opacity 0.3s;
     78 |   transition: opacity 0.3s;
     79 |   opacity: 0;
     80 | }
     81 | 
     82 | .lazy-loaded { opacity: 1; }
     83 | 
    84 |
    85 |
  6. 86 |
87 | 88 |
89 |

Demo

90 |

Open up your Developer Tools / Firebug to peek at the network.

91 |

On mobile, image order will be swapped (different images used).

92 |

Images courtesy of NASA.

93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 |
109 | 110 |
111 | 115 |
116 | 117 | 120 | 121 | 122 | 123 | 124 | 125 | --------------------------------------------------------------------------------