Skip to content

Instantly share code, notes, and snippets.

@scamartist26
Created July 19, 2018 16:06
Show Gist options
  • Save scamartist26/75be53d4a4bd9f470d540f0089443032 to your computer and use it in GitHub Desktop.
Save scamartist26/75be53d4a4bd9f470d540f0089443032 to your computer and use it in GitHub Desktop.
Lazy Load for Background Images (using JS)
<h1>Lazy Load for background Images</h1>
<div data-background-image-url="https://s3-us-west-2.amazonaws.com/s.cdpn.io/25381/tumblr_mrraktQTCS1st5lhmo1_1280.jpg"></div>
<div data-background-image-url="https://s3-us-west-2.amazonaws.com/s.cdpn.io/25381/tumblr_mufr0mmWYW1st5lhmo1_1280.jpg"></div>
<div data-background-image-url="https://s3-us-west-2.amazonaws.com/s.cdpn.io/25381/tumblr_mr80snx79b1st5lhmo1_1280.jpg"></div>
<div data-background-image-url="https://s3-us-west-2.amazonaws.com/s.cdpn.io/25381/tumblr_mrraktQTCS1st5lhmo1_1280.jpg"></div>
<div data-background-image-url="https://s3-us-west-2.amazonaws.com/s.cdpn.io/25381/tumblr_msuei3sMTo1st5lhmo1_1280.jpg"></div>
<div data-background-image-url="https://s3-us-west-2.amazonaws.com/s.cdpn.io/25381/tumblr_mtw7mhZsCe1st5lhmo1_1280.jpg"></div>
<div data-background-image-url="https://s3-us-west-2.amazonaws.com/s.cdpn.io/25381/tumblr_msuei3sMTo1st5lhmo1_1280.jpg"></div>
<div data-background-image-url="https://s3-us-west-2.amazonaws.com/s.cdpn.io/25381/tumblr_mufrlh9WqW1st5lhmo1_1280.jpg"></div>

Lazy Load for Background Images (using JS)

This is an update to an old pen: https://codepen.io/the_ruther4d/details/aEGAJ

This version uses javascript to load the image, so that we can wait to start our transition after we know the image is ready. It uses the Intersection Observer API. There's a polyfill included for browsers without support.

A Pen by Rosh Jutherford on CodePen.

License.

function BackgroundNode({node, loadedClassName}) {
let src = node.getAttribute('data-background-image-url');
let show = (onComplete) => {
requestAnimationFrame(() => {
node.style.backgroundImage = `url(${src})`
node.classList.add(loadedClassName);
onComplete();
})
}
return {
node,
// onComplete is called after the image is done loading.
load: (onComplete) => {
let img = new Image();
img.onload = show(onComplete);
img.src = src;
}
}
}
let defaultOptions = {
selector: '[data-background-image-url]',
loadedClassName: 'loaded'
}
function BackgroundLazyLoader({selector, loadedClassName} = defaultOptions) {
let nodes = [].slice.apply(document.querySelectorAll(selector))
.map(node => new BackgroundNode({node, loadedClassName}));
let callback = (entries, observer) => {
entries.forEach(({target, isIntersecting}) => {
if (!isIntersecting) {
return;
}
let obj = nodes.find(it => it.node.isSameNode(target));
if (obj) {
obj.load(() => {
// Unobserve the node:
observer.unobserve(target);
// Remove this node from our list:
nodes = nodes.filter(n => !n.node.isSameNode(target));
// If there are no remaining unloaded nodes,
// disconnect the observer since we don't need it anymore.
if (!nodes.length) {
observer.disconnect();
}
});
}
})
};
let observer = new IntersectionObserver(callback);
nodes.forEach(node => observer.observe(node.node));
};
BackgroundLazyLoader();
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
html {
background: rgba(200,200,200,0.3);
backface-visibility: hidden;
}
h1 {
width: 100%;
text-align: center;
font-weight: 100;
padding-top: 20px;
color: rgba(200,200,200,1)
}
div {
width: 300px;
height: 300px;
margin: 150px auto;
position: relative;
background-position: center center;
background-repeat: no-repeat;
background-size: cover;
}
div:after {
content: '';
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
background: rgba(200,200,200,0.5);
transition: opacity 0.5s ease;
}
div.loaded:after {
opacity: 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment