Skip to content

Instantly share code, notes, and snippets.

@davidpaulsson
Last active February 3, 2016 03:24
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save davidpaulsson/10101172 to your computer and use it in GitHub Desktop.
Save davidpaulsson/10101172 to your computer and use it in GitHub Desktop.
Lazy loading with padding-bottom hack for responsive images
/**
* Place this inline at the bottom of the html document, right before
* closing `</body>`. It's important to have this inline as we want to
* display images asap.
*
* Markup example for the actual images. It also calculates the image
* container using the [padding-top hack](https://gist.github.com/davidpaulsson/10101985),
* please do this calculation on the back end, before drawing the DOM.
* Current example can load three images sizes, customize to fit your needs. It
* also adds the calculated image URL as an data-original tag on the img element it creates,
* making it play well with [jQuery Lazy Load](http://www.appelsiini.net/projects/lazyload).
*
<div class="img-container" style="padding-top:((image.Height / image.Width) * 100))%">
<noscript data-src-small="@image.GetUrl(ImageSize.Small)"
data-src-medium="@image.GetUrl(ImageSize.Medium)"
data-src-large="@image.GetUrl(ImageSize.Large)"
data-src-width="@image.Width"
data-src-height="@image.Height"
data-alt="@image.Text">
<img src="@image.GetUrl(ImageSize.Small)" alt="@image.Text">
</noscript>
</div>
*
* If you want the image to load directly, as a normal `<img>` tag, just
* add `data-src-fast="yes"` to the `noscript` tag and the calculated
* URL will be added as the src attribute on the img element it creates.
*
*/
(function(win) {
'use strict';
// Get screen pixel ratio
var screenPixelRatio = function() {
var retVal = 1;
if (win.devicePixelRatio) {
retVal = win.devicePixelRatio;
} else if ("matchMedia" in win && win.matchMedia) {
if (win.matchMedia("(min-resolution: 2dppx)").matches || win.matchMedia("(min-resolution: 192dpi)").matches) {
retVal = 2;
} else if (win.matchMedia("(min-resolution: 1.5dppx)").matches || win.matchMedia("(min-resolution: 144dpi)").matches) {
retVal = 1.5;
}
}
return retVal;
},
// Get the most suitable image
getImageVersion = function() {
var pixelRatio = screenPixelRatio();
var width = (window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth) * pixelRatio;
if (width <= 640) {
return "small";
} else if (width <= 1024) {
return "medium";
} else {
return "large";
}
},
// Load images
lazyloadImage = function(imageContainer) {
var imageVersion = getImageVersion();
if (!imageContainer || !imageContainer.children) {
return;
}
var img = imageContainer.children[0];
if (img) {
var imgSRC = img.getAttribute("data-src-" + imageVersion);
var altTxt = img.getAttribute("data-alt");
var imgHeight = img.getAttribute("data-src-height");
var imgWidth = img.getAttribute("data-src-width");
var fast = img.getAttribute("data-src-fast");
if (fast) {
try {
var imageElement = new Image();
imageElement.src = imgSRC;
imageElement.setAttribute("height", imgHeight);
imageElement.setAttribute("width", imgWidth);
imageElement.setAttribute("alt", altTxt ? altTxt : "");
imageContainer.appendChild(imageElement);
} catch (e) {
console.log("img error" + e);
}
imageContainer.removeChild(imageContainer.children[0]);
} else if (imgSRC) {
try {
var imageElement = new Image();
imageElement.setAttribute("class", "lazy");
imageElement.setAttribute("data-original", imgSRC);
imageElement.setAttribute("height", imgHeight);
imageElement.setAttribute("width", imgWidth);
imageElement.setAttribute("alt", altTxt ? altTxt : "");
imageContainer.appendChild(imageElement);
} catch (e) {
console.log("img error" + e);
}
imageContainer.removeChild(imageContainer.children[0]);
}
}
},
lazyLoadedImages = document.getElementsByClassName ? document.getElementsByClassName("img-container") : document.querySelectorAll(".img-container");
for (var i = 0, length = lazyLoadedImages.length; i < length; i++) {
lazyloadImage(lazyLoadedImages[i]);
}
})(window);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment