Vanilla JS Lightbox Challenge
Are lightboxes tricky to build? My experience leads me to think yes. I’ve managed to put something together that works as long as I know the number of imgs and URLs to reference. I need to learn how to attach a click event to each a element that can trigger the lightbox. Just typing this out gives me an idea… HUZZAH! I figured it out. It’s not perfect, but I’m so dang happy that came to me.
View the code:
HTML and JS
<div class="code-block">
<div class="photo-grid">
<a href="https://jeremycaudle.com/ygg/resources/onebitme.png" class="lightbox-url" ><img src="https://jeremycaudle.com/ygg/resources/onebitme.png" class="lightbox-img" width="480" height="389" alt="Jeremy Caudle saying hello."></a>
<a href="https://jeremycaudle.com/ygg/resources/onebitme.png" class="lightbox-url"><img src="https://jeremycaudle.com/ygg/resources/onebitme.png" class="lightbox-img" width="480" height="389" alt="Goofy man holding up his hand."></a>
<p id="lightbox-status-message">Lightbox test...</p>
</div>
</div>
<div id="lightbox" class="hidden">
<div>
<img id="lightbox-img" src="" alt="">
<button id="lightbox-button">Close</button>
</div>
</div>
<script>
// ---------
// Variables
// ---------
const lightboxMessage = document.getElementById('lightbox-status-message');
const lightbox = document.getElementById('lightbox');
const lightboxIMG = document.getElementById('lightbox-img');
const lightboxCaption = document.getElementById('lightbox-caption');
const lightboxButton = document.getElementById('lightbox-button');
const lightboxImgs = [];
const lightboxURLs = [];
// ---------
// Functions
// ---------
function showLightbox(e) {
lightbox.setAttribute('class', '');
lightbox.style.visibility = 'visible';
lightbox.style.opacity = '1';
console.log('Show lightbox.');
lightboxIMG.setAttribute('src', this.getAttribute('data-url'));
}
function hideLightbox(e) {
lightbox.setAttribute('class', 'hidden');
lightbox.style.visibility = 'hidden';
lightbox.style.opacity = '0';
console.log('Hide lightbox.');
lightboxIMG.setAttribute('src', '');
}
// ---------
// Events
// ---------
window.onload = function () {
const lightboxImgs = document.getElementsByClassName('lightbox-img');
const lightboxURLs = document.getElementsByClassName('lightbox-url');
lightboxMessage.textContent = `${lightboxURLs.length} URLs detected and ${lightboxImgs.length} IMGs detected.`;
for (let i = 0; i < lightboxURLs.length; i++) {
lightboxURLs[i].setAttribute('data-url',lightboxURLs[i].getAttribute('href'));
lightboxURLs[i].setAttribute('href','#');
lightboxURLs[i].setAttribute('id',`lightbox-link-${[i]}`);
document.querySelector(`#lightbox-link-${[i]}`).addEventListener('click', showLightbox);
}
for (let i = 0; i < lightboxImgs.length; i++) {
lightboxImgs[i].getAttribute('data-url');
lightboxImgs[i].style.border = "inset 1px white";
}
};
lightboxButton.addEventListener('click', hideLightbox);
</script>
CSS
#lightbox.hidden {
display: none;
}
#lightbox img {
background-color: orange;
box-shadow: 0 0 1rem 0 rgba(0,0,0,.2);
}
#lightbox button {
background: transparent;
border: solid white 3px;
color: white;
display: block;
width: 7em;
margin: 1rem auto;
cursor: pointer;
}
#lightbox button:hover, #lightbox button:focus {
color: orange;
border-color: orange;
}
@supports (display: grid) {
.photo-grid {
display: grid;
place-items: center;
width: 100%;
max-width: 30em;
margin: 1rem auto;
padding: 1rem;
background-color: #777;
gap: 1rem;
grid-template-columns: 1fr 2fr;
grid-template-rows: 1fr 3rem;
height: auto;
}
.photo-grid a {
display: block;
width: 100%;
height: 100%;
}
.photo-grid img {
object-fit: fill;
max-width: 100%;
height: auto;
}
.photo-grid p {
margin: 0;
font-family: Helvetica, Arial, sans-serif;
grid-column: 1 / span 2;
color: orange;
padding: 1rem 0;
}
#lightbox {
display: grid;
width: 100%;
height: 100%;
overflow:hidden;
position: absolute;
top: 0;
left: 0;
place-items: center;
background-color: #333;
opacity: 0;
transition: opacity .33s ease-out;
visibility: hidden;
}
}