Skip to content

Instantly share code, notes, and snippets.

@karlcow
Created March 25, 2021 13:28
Show Gist options
  • Save karlcow/43c64d715a0fdde0b68915e4e61d6e46 to your computer and use it in GitHub Desktop.
Save karlcow/43c64d715a0fdde0b68915e4e61d6e46 to your computer and use it in GitHub Desktop.
(function (containerId, opts) {
if (!('querySelector' in document)) return;
var container = document.getElementById(containerId);
var nameSpace = opts.namespace || '';
var onResize = throttle(update, 200);
var waiting = !!window.IntersectionObserver;
var observer;
update();
document.addEventListener('DOMContentLoaded', update);
window.addEventListener('resize', onResize);
// NYT Scoop-specific code
if (opts.setup) {
opts.setup(container).on('cleanup', cleanup);
}
function cleanup() {
document.removeEventListener('DOMContentLoaded', update);
window.removeEventListener('resize', onResize);
if (observer) observer.disconnect();
}
function update() {
var artboards = selectChildren('.' + nameSpace + 'artboard[data-min-width]', container),
width = Math.round(container.getBoundingClientRect().width);
// Set artboard visibility based on container width
artboards.forEach(function(el) {
var minwidth = el.getAttribute('data-min-width'),
maxwidth = el.getAttribute('data-max-width');
if (+minwidth <= width && (+maxwidth >= width || maxwidth === null)) {
if (!waiting) {
selectChildren('.' + nameSpace + 'aiImg', el).forEach(updateImgSrc);
}
el.style.display = 'block';
} else {
el.style.display = 'none';
}
});
// Initialize lazy loading on first call
if (waiting && !observer) {
if (elementInView(container)) {
waiting = false;
update();
} else {
observer = new IntersectionObserver(onIntersectionChange, {});
observer.observe(container);
}
}
}
function elementInView(el) {
var bounds = el.getBoundingClientRect();
return bounds.top < window.innerHeight && bounds.bottom > 0;
}
// Replace blank placeholder image with actual image
function updateImgSrc(img) {
var src = img.getAttribute('data-src');
if (src && img.getAttribute('src') != src) {
img.setAttribute('src', src);
}
}
function onIntersectionChange(entries) {
// There may be multiple entries relating to the same container
// (captured at different times)
var isIntersecting = entries.reduce(function(memo, entry) {
return memo || entry.isIntersecting;
}, false);
if (isIntersecting) {
waiting = false;
// update: don't remove -- we need the observer to trigger an update
// when a hidden map becomes visible after user interaction
// (e.g. when an accordion menu or tab opens)
// observer.disconnect();
// observer = null;
update();
}
}
function selectChildren(selector, parent) {
return parent ? Array.prototype.slice.call(parent.querySelectorAll(selector)) : [];
}
// based on underscore.js
function throttle(func, wait) {
var timeout = null, previous = 0;
function run() {
previous = Date.now();
timeout = null;
func();
}
return function() {
var remaining = wait - (Date.now() - previous);
if (remaining <= 0 || remaining > wait) {
clearTimeout(timeout);
run();
} else if (!timeout) {
timeout = setTimeout(run, remaining);
}
};
}
})("g-transit-small-multiples-box", {namespace: "g-", setup: window.setupInteractive || window.getComponent});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment