0

Looking for some support on why this loop is not applying the eventlisteners to the 2 image elements.

HTML:

<img src="video-embed.jpg" alt="text content">
<img src="video-embed-copy.jpg" alt="text content">

JAVASCRIPT:

let videoThumbnails = document.querySelectorAll('img[src*="video-embed"]');
    
function toggleGalleryModal(modal) {
    console.log(clicked);
    document.getElementById(modal).classList.toggle("show-modal");
}
    
function buildGalleryModals() {
    
    videoThumbnails.forEach(function (thumbnail, index) {
        let modalID = 'vid-gallery-modal-' + index,
            altText = thumbnail.alt;
    
        thumbnail.addEventListener('click', function (event) {
            console.log('thumbnail[i]: ' + index);
        });
    
        document.body.innerHTML += '<div id="' + modalID + '" class="vid-gallery-modal"><div class="modal-content"><span class="close-button">×</span>' + altText + '</div></div>';
    });
}
    
buildGalleryModals();
2
  • have you verified that videoThumbnails contains the two expected DOM elements? Commented Jul 13, 2020 at 20:56
  • Yes, the elements exist. The modals actually generate (both) at the end of the body, but they do not receive the click listeners. Commented Jul 13, 2020 at 23:15

2 Answers 2

2

The problem is that after you set up the click handlers, you overwrite the document.body.innerHTML with new HTML elements and wipe out the elements that you just set up.

Instead, inject that new HTML into a portion of the document, but not the document.body.

let videoThumbnails = document.querySelectorAll('img[src*="video-embed"]');

function toggleGalleryModal(modal) {
    console.log(clicked);
    document.getElementById(modal).classList.toggle("show-modal");
}

function buildGalleryModals() {

    videoThumbnails.forEach(function (thumbnail, index) {
        let modalID = 'vid-gallery-modal-' + index, 
            altText = thumbnail.alt;

        thumbnail.addEventListener('click', function (event) {
            console.log('thumbnail[i]: ' + index);
        });

        document.getElementById("output").innerHTML += '<div id="' + modalID + '" class="vid-gallery-modal"><div class="modal-content"><span class="close-button">×</span>' + altText + '</div></div>';
    });
}

buildGalleryModals();
<img src="video-embed.jpg" alt="text content1">
<img src="video-embed-copy.jpg" alt="text content2">
<div id="output"></div>

Sign up to request clarification or add additional context in comments.

2 Comments

does the += overwrite the entire existing innerHTML on document.body?
@Anthony In short, yes. What happens is that it gets a string representation of the DOM elements and concatenates your new string to it. This causes any event handlers that might have been set up on those initial elements to be discarded. And, because you are doing this in a loop, it happens over and over again. You wind up with all the HTML, but no handlers because the system sees it as new HTML replacing the old HTML and to the JS runtime, that means new objects replacing the old ones.
0

The assignments inside the forEach() will not change the original array elements (i.e. videoThumbnails) as they operate on a copy of the array elements, and not the array elements themselves:

myArray = [1,2,3,4,5]

// try to assign new value to array elements using forEach
myArray.forEach(e => {
            e = '0';
            console.log(e);
        }
    )

// see that elements in original array are unchanged
myArray.forEach(e => {
            console.log(e);
        }
    )

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.