vue-cool-lightbox
Version:
A pretty Vue.js component to display an image gallery lightbox inspired by fancybox
75 lines (68 loc) • 1.94 kB
JavaScript
const attributes = ['media', 'srcset', 'sizes', 'src'];
export default {
inserted: el => {
function loadImage() {
const imageElement = findChild(el, 'img')
const pictureElement = findChild(el, 'picture')
if (imageElement) {
setLoadListeners(imageElement)
swapAttributes(imageElement)
} else if (pictureElement) {
const pictureImg = findChild(pictureElement, 'img');
const pictureSources = Array.from(pictureElement.children).filter(
child => child.nodeName === "SOURCE"
);
if (pictureImg) {
setLoadListeners(pictureImg)
if (pictureSources.length) {
pictureSources.forEach(source => {
swapAttributes(source)
})
}
swapAttributes(pictureImg)
}
}
}
function handleIntersect(entries, observer) {
entries.forEach(entry => {
if (entry.isIntersecting) {
loadImage();
observer.unobserve(el);
}
});
}
function createObserver() {
const options = {
root: null,
threshold: "0"
};
const observer = new IntersectionObserver(handleIntersect, options);
observer.observe(el);
}
if (window["IntersectionObserver"]) {
createObserver();
} else {
loadImage();
}
}
};
function swapAttributes(el) {
attributes.forEach((attribute) => {
const dataAttribute = el.dataset[attribute];
if (dataAttribute) {
el[attribute] = dataAttribute;
el.removeAttribute(`data-${attribute}`)
}
})
}
function setLoadListeners(el) {
el.addEventListener("load", () => {
setTimeout(() => el.classList.add("loaded"), 100);
});
el.addEventListener("error", () => console.log("error"));
}
function findChild(parent, nodeName) {
return Array.from(parent.children).find(
el => el.nodeName === nodeName.toUpperCase()
);
}