Skip to content

Instantly share code, notes, and snippets.

@michaelhue
Last active February 16, 2016 19:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save michaelhue/d18b638916e1931cd389 to your computer and use it in GitHub Desktop.
Save michaelhue/d18b638916e1931cd389 to your computer and use it in GitHub Desktop.
JS viewport-aware image lazy loading
/**
* Minimal viewport-aware lazy loading for images.
*
* This is a simple vanilla JS script for async image loading
* shortly before the element enters the viewport.
*
* Example:
*
* <div class="img-container" data-ll='{"src": "myimage.jpg", "alt": "My Image"}'>
* <noscript><img src="myimage.jpg" alt="My Image"></noscript>
* </div>
*
*/
(function () {
var viewportScale = 1.5;
var elements = document.querySelectorAll('[data-ll]');
var queue = Array.prototype.slice.call(elements);
// Load and insert an image.
function loadImage (el) {
var img = document.createElement('img');
var attrs = JSON.parse(el.dataset.ll);
for (var k in attrs) img.setAttribute(k, attrs[k]);
img.addEventListener('load', function () {
el.removeAttribute('data-ll');
el.appendChild(img);
});
}
// Check if an element is inside viewport bounds.
function shouldLoad (el) {
return el.getBoundingClientRect().top < (viewportScale * document.documentElement.clientHeight);
}
// Recalculate visible elements.
function recalculate () {
queue.filter(shouldLoad).forEach(function (el) {
queue.splice(queue.indexOf(el), 1);
loadImage(el);
});
if (queue.length < 1) detach();
}
// Attach event listeners to window.
function attach () {
window.addEventListener('scroll', recalculate);
window.addEventListener('resize', recalculate);
}
// Detach event listeners from window.
function detach () {
window.removeEventListener('scroll', recalculate);
window.removeEventListener('resize', recalculate);
}
// Initialize.
recalculate();
attach();
})();
// Minimal viewport-aware lazy loading for images.
!function(){function e(e){var t=document.createElement("img"),n=JSON.parse(e.dataset.ll);for(var i in n)t.setAttribute(i,n[i]);t.addEventListener("load",function(){e.removeAttribute("data-ll"),e.appendChild(t)})}function t(e){return e.getBoundingClientRect().top<r*document.documentElement.clientHeight}function n(){c.filter(t).forEach(function(t){c.splice(c.indexOf(t),1),e(t)}),c.length<1&&o()}function i(){window.addEventListener("scroll",n),window.addEventListener("resize",n)}function o(){window.removeEventListener("scroll",n),window.removeEventListener("resize",n)}var r=1.5,l=document.querySelectorAll("[data-ll]"),c=Array.prototype.slice.call(l);n(),i()}();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment