Skip to content

Instantly share code, notes, and snippets.

@cobbweb
Created December 9, 2015 04:43
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save cobbweb/bc71fbeece64479533d3 to your computer and use it in GitHub Desktop.
Save cobbweb/bc71fbeece64479533d3 to your computer and use it in GitHub Desktop.
Lazyload Children
(function(window) {
'use strict';
var raf = window.requestAnimationFrame;
var CLOSESNESS = 2;
function startLoop(fn) {
var running = false;
var lastExit;
(function animLoop() {
// stop looping if lastExit was 1
if (lastExit === 1) {
return;
}
raf(animLoop);
if (running) {
return;
}
running = true;
lastExit = fn();
running = false;
})();
}
/**
* Absolute elements lose their 'real' offsetTop value.
* This function calculate how far down the page an element really is.
*/
function getTrueOffsetTop(element) {
var offset = 0;
var nextEl = element;
do {
offset += nextEl.offsetTop;
nextEl = nextEl.offsetParent;
} while (nextEl);
return offset;
}
function calculateClosenesss(offsetTop, offsetHeight, viewportHeight, scrollY) {
var offsetHalf = offsetTop + (offsetHeight / 2);
var scrollYHalf = scrollY + (viewportHeight / 2);
var distanceToElement;
// defensively add one to prevent division by zero below
offsetHeight += 1;
if (offsetHalf > scrollYHalf) {
distanceToElement = offsetHalf - scrollYHalf;
return (distanceToElement / offsetHeight);
} else if (offsetHeight < scrollYHalf) {
distanceToElement = scrollYHalf - offsetHalf;
return (distanceToElement / offsetHeight);
} else {
return 0;
}
}
function watchElementLoop(watchElement, cb) {
return function() {
var offsetTop = getTrueOffsetTop(watchElement);
var offsetHeight = watchElement.offsetHeight;
var scrollY = window.scrollY;
var viewportHeight = document.documentElement.clientHeight;
var closeness = calculateClosenesss(offsetTop, offsetHeight, viewportHeight, scrollY);
if (closeness <= CLOSESNESS) {
cb();
// one = stop looping now
return 1;
} else {
// zero = keep looping
return 0;
}
};
}
function lazyloadChildren(parent) {
var childrenSelector = parent.getAttribute('data-lazyload-children');
var children = parent.querySelectorAll(childrenSelector);
// Bail out if we didn't find the children element to lazyload
if (!children) {
if (console && console.warn) {
console.warn('Could not find children in %s using select: ', parent, childrenSelector);
}
return;
}
startLoop(watchElementLoop(parent, function() {
for (var i = 0, l = children.length; i < l; i++) {
lazySizes.loader.unveil(children[i]);
}
}));
}
var parentElements = document.querySelectorAll('[data-lazyload-children]');
for (var i = 0, l = parentElements.length; i < l; i++) {
lazyloadChildren(parentElements[i]);
}
})(window);
@darana
Copy link

darana commented Sep 5, 2017

Just wanted to say Thanks for sharing this. I slotted it in to lazysizes 3 on my ecomm shop to lazy load our hidden images and it works great! Cut my initial page download basically in half. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment