Vanilla JS Lightbox Challenge


by Jeremy Caudle
code

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.

Jeremy Caudle saying hello. Goofy man holding up his hand.

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;
            }

        }