39 |
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 | Include lazyload.min.js
or inline it.
62 |
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 |
70 |
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 |
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 |
--------------------------------------------------------------------------------
/javascripts/lazyload.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() {
9 | var addEventListener = window.addEventListener || function(n,f) { window.attachEvent('on'+n, f); },
10 | removeEventListener = window.removeEventListener || function(n,f,b) { window.detachEvent('on'+n, f); };
11 |
12 | var lazyLoader = {
13 | cache: [],
14 | mobileScreenSize: 500,
15 | //tinyGif: 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==',
16 |
17 | addObservers: function() {
18 | addEventListener('scroll', lazyLoader.throttledLoad);
19 | addEventListener('resize', lazyLoader.throttledLoad);
20 | },
21 |
22 | removeObservers: function() {
23 | removeEventListener('scroll', lazyLoader.throttledLoad, false);
24 | removeEventListener('resize', lazyLoader.throttledLoad, false);
25 | },
26 |
27 | throttleTimer: new Date().getTime(),
28 |
29 | throttledLoad: function() {
30 | var now = new Date().getTime();
31 | if ((now - lazyLoader.throttleTimer) >= 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 |
--------------------------------------------------------------------------------
/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