I’m working on my portfolio, and I want to create a Lightbox that activates when a user clicks on an image.
The images are added to the dom via a javascript that fetches a json file with the paths to the images :
const imagesData = "images.json"
const display = document.getElementById("grid-container")
const getData = async () => {
const response = await fetch(imagesData)
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`)
}
const data = await response.json()
return data
}
const displayImages =async () => {
const content = await getData()
let dataDisplay = content.map((object) => {
return `
<div class="grid-item">
<img src="${object.path}" alt="${object.name}" class="grid-image">
</div>
`
}).join("")
display.innerHTML = dataDisplay
}
displayImages()
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>Grille et lightbox</title>
<meta name="author" content="Benoît Aguesse" />
<meta name="description" content="description" />
<link href="styles.css" rel="stylesheet" />
<script src="grille.js" defer></script>
<script src="lightbox.js" defer></script>
</head>
<body>
<h1>Photo gallery</h1>
<p>Click on an image</p>
<div id="grid-container"></div>
<!-- <div class="lightbox show">
<button class="lightbox-close">Fermer</button>
<button class="lightbox-next">Suivant</button>
<button class="lightbox-previous">Précédent</button>
<div class="lightbox-container">
<img src="images/Hourtin 1.jpeg" alt="" class="lightbox-image">
</div>
<span class="lightbox-info">
<p>Titre</p>
<p>Description</p>
<p>Métadonnées</p>
</span>
</div> -->
</body>
</html>
*The commented html bit is a draft to setup the Lightbox content and layout
I tried following different tutorials on implementing a Lightbox, but none really worked… I’m relatively new to javascript but this an opportunity to learn ! the functionalities I’m looking for are :
- opening the Lightbox showing a larger (better resolution) version of the clicked image, the title and some metadata that are stored in the json file used to create the image grid
- having a “close”, “previous” and “next” button to cycle trough the images while being in the Lightbox (ideally it also recognizes arrow keystrokes and swipe gestures, if possible)
What are the general principles or best practices to guide me on the approach to have ? Should I build the Lightbox in html and uses javascript to activate it and modify it to cycle trough the images, or use javascript to create html on the fly ?
I tried wrapping the images in a <a>
tag and using javascript to prevent the default behavior and use the link to display the image in the Lightbox but it did not prevent the default behavior, the image still opened as a file :
class Lightbox {
static init() {
const links = document.querySelectorAll('a[href$=".jpeg"]')
.forEach(link => link.addEventListener('click', e => {
e.preventDefault()
new Lightbox(e.currentTarget.getAttribute('href'))
}))
}
constructor(url) {
const element = this.buildDOM(url)
document.body.appendChild(element)
}
buildDOM(url) {
const dom = document.createElement('div')
dom.classList.add('lightbox')
dom.innerHTML = `
<button class="lightbox-close">Fermer</button>
<button class="lightbox-next">Suivant</button>
<button class="lightbox-previous">Précédent</button>
<div class="lightbox-container">
<img src="${url}" alt="" class="lightbox-image">
</div>
`
return dom
}
}