Skip to content

Instantly share code, notes, and snippets.

@johannschopplich
Created July 10, 2020 10:12
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 johannschopplich/7a72e7b16c737e6d075cedc1c8d0db29 to your computer and use it in GitHub Desktop.
Save johannschopplich/7a72e7b16c737e6d075cedc1c8d0db29 to your computer and use it in GitHub Desktop.
Web component to preload images
const nanoid = () => Math.random().toString(36).substring(2)
/**
* @module PreloadImages
* @description
* Custom element to preload images
* @property {(string|array)} src Comma seperated list, array or string of image source(s)
*/
export default class PreloadImages extends HTMLElement {
constructor () {
super()
this.i = nanoid()
this.dataset.i = this.i
this.setAttribute('aria-hidden', 'true')
if (!document.getElementById(this.i)) {
const styleElement = document.createElement('style')
styleElement.id = this.i
styleElement.innerHTML = `
[data-i="${this.i}"] {
position: absolute;
width: 1px;
height: auto;
clip: rect(0 0 0 0);
border: 0;
padding: 0;
margin: 0;
overflow: hidden;
white-space: nowrap;
}
`.replace(/\s\s+/g, ' ').trim()
document.head.appendChild(styleElement)
}
this.render = () => {
const srcValue = this.src.trim()
let images = []
if (!srcValue) {
console.error('[PreloadImages] No images given.')
return
}
if (srcValue.startsWith('[')) {
try {
images = JSON.parse(srcValue)
} catch (error) {
console.error('[PreloadImages] Component `src` attribute is not valid JSON.')
}
} else if (srcValue.includes(',')) {
// Comma seperated list of image sources
images = srcValue.split(',')
} else {
// Just one image source
images.push(srcValue)
}
// Remove duplicates from the iterable `images`
images = [...new Set(images)]
const markup = images.map(value => `
<img src="${value}" alt="">
`).join('')
// This method doesn't reparse the element it is being used on, thus avoids
// the extra step of serialization, making it much faster than direct innerHTML manipulation
this.insertAdjacentHTML('beforeend', markup)
}
}
get src () {
return this.getAttribute('src')
}
set src (val) {
return this.setAttribute('src', val)
}
static get observedAttributes () {
return ['src']
}
connectedCallback () {
this.render()
}
attributeChangedCallback () {
this.render()
}
}
customElements.define('preload-images', PreloadImages)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment