Last active
April 11, 2023 13:31
-
-
Save geomago/e19bb94d10631b310a38eb5b89596af4 to your computer and use it in GitHub Desktop.
Standard Web Component as a wrapper to Glide.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// WebComponent image-carousel, a wrapper for glide.js | |
class ImageCarousel extends HTMLElement { | |
constructor() { | |
super(); | |
} | |
connectedCallback() { | |
// Load glide.js once | |
if (typeof Glide === 'undefined') { // "Glide" does not exists | |
if (!window.jsGlide) { // not already running (no other instance of the same WC) | |
const script = document.createElement('script'); | |
script.src = "https://cdn.jsdelivr.net/npm/@glidejs/[email protected]/dist/glide.min.js"; | |
document.body.appendChild(script); | |
script.addEventListener('load', () => { | |
window.jsGlide = 'avail'; // when script is fully loaded, mark it "available" | |
}); | |
const link1 = document.createElement('link'); | |
link1.rel = "stylesheet"; | |
link1.href = "https://cdn.jsdelivr.net/npm/@glidejs/[email protected]/dist/css/glide.core.min.css"; | |
document.head.appendChild(link1); // in main doc, to be able to change styles | |
const link2 = document.createElement('link'); | |
link2.rel = "stylesheet"; | |
link2.href = "https://cdn.jsdelivr.net/npm/@glidejs/[email protected]/dist/css/glide.theme.min.css"; | |
document.head.appendChild(link2); // in main doc, to be able to change styles | |
window.jsGlide = 'loading'; | |
} | |
} else if (typeof Glide !== 'function') { // "Glide" exists but it is not a function | |
alert("Name conflict: glide.js not loadable, the name 'Glide' is already in use"); | |
return; | |
} else { // "Glide" exists and it is a function: therefore glide.js is available | |
window.jsGlide = 'avail'; | |
} | |
var wc = this; | |
// Wait till the script is loaded | |
var interval = setInterval(() => { | |
if (window.jsGlide === 'avail' && typeof Glide === 'function') { | |
clearInterval(interval); // remove the timer | |
// Get the array of all images | |
var images = wc.querySelectorAll('img'); | |
var items = []; | |
var buttons = []; | |
images.forEach((elem, index) => { | |
items.push(`<li class="glide__slide">${elem.outerHTML}</li>`); | |
buttons.push(`<button class="glide__bullet" data-glide-dir="=${index}"></button>`); | |
}); | |
// Create the container skeleton | |
var id = (wc.id || 'ig' + Math.random().toString().substring(2, 8)); | |
wc.innerHTML = ` | |
<div class="glide"> | |
<div class="glide__track" data-glide-el="track"> | |
<ul id="${id}_list" class="glide__slides"> | |
${items.join('\n')} | |
</ul> | |
</div> | |
<div class="glide__arrows" data-glide-el="controls"> | |
<button class="glide__arrow glide__arrow--left" data-glide-dir="<"><</button> | |
<button class="glide__arrow glide__arrow--right" data-glide-dir=">">></button> | |
</div> | |
<div id="${id}_dots" class="glide__bullets" data-glide-el="controls[nav]"> | |
${buttons.join('\n')} | |
</div> | |
</div>`; | |
// Add possible config options from the data-*** attributes | |
var options = Object.assign( | |
{ | |
type: 'carousel', | |
focus: 'atCenter', | |
perView: 1, | |
startAt: 0 | |
}, wc.dataset); | |
// Activate the Glide.js carousel | |
const glide = new Glide('.glide', options); | |
glide.mount(); | |
} | |
}, 20) | |
} | |
// Utility function to transform a JS literal into a JS object | |
getObjectFromString(string) { | |
const getobj = new Function(`return ${string}`); | |
try { | |
const obj = getobj(); | |
return obj; | |
} catch (error) { | |
throw ('Invalid JavaScript object string: ' + string); | |
} | |
} | |
} | |
customElements.define('image-carousel', ImageCarousel); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment