Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript issues regarding events for dynamically created HTML

I have some issues with targeting dynamically created elements with JavaScript.

Issue 1

Shortened JavaScript code:

var lightbox = document.createElement('div'),
    nav = document.createElement("nav"),
    imga = document.querySelectorAll(".gallery a");
for (i = 0; i < imga.length; i++) {
    imga[i].addEventListener("click", function() {
        document.body.insertBefore(lightbox, document.body.firstChild);
        lightbox.appendChild(nav);
    });
}

1: Now I want to make an event on my <nav>. How do I get the event to target #lightbox nav a instead of just #lightbox nav?

nav.addEventListener("click", function() {
    // works, but I want to target only the <a> links inside
});

I've tried many things, like this:

var selector = document.querySelectorAll("nav a");
for (i = 0; i < selector.length; i++) {
    selector[i].addEventListener("click", function() {
        // doesn't work because the <nav> is inserted dynamically
    });
}

And this:

var selector = nav.getElementsByTagName("a");
for (i = 0; i < selector.length; i++) {
    selector[i].addEventListener("click", function() {
        // doesn't work because the <nav> is inserted dynamically
    });
}

Issue 2

Shortened JavaScript code:

var img,
    imga = document.querySelectorAll(".gallery a");
for (i = 0; i < imga.length; i++) {
    imga[i].addEventListener("click", function() {
            for (i = 0; i < imga.length; i++) {
                img = document.createElement("img");
                lightbox.appendChild(img);
            }
    });
}

2: How do I add an event to the dynamically created #lightbox img? The img = document.createElement("img") has to be inside of the function to append multiple images, and for that reason I can't do like this (like currently on <nav>):

img.addEventListener("click", function() {
    // doesn't work because img = document.createElement("img")
    // has to be inside another function
});

Can somebody please assist me on this? I'm not very experienced in JavaScript.

like image 747
mnsth Avatar asked Oct 20 '22 20:10

mnsth


1 Answers

Issue 2

The easy solution is to add the event handler to all the elements inside the loop

var img,
    imga = document.querySelectorAll(".gallery a");

for (i = 0; i < imga.length; i++) {
    imga[i].addEventListener("click", function() {
        for (i = 0; i < imga.length; i++) {
            img = document.createElement("img");
            img.setAttribute("src", imga[i].getAttribute("href"));
            lightbox.appendChild(img);

            img.addEventListener('click', fn, false);
        }
    });
}

the somewhat harder solution is to use delegated event handlers

var img,
    imga = document.querySelectorAll(".gallery a");

lightbox.addEventListener('click', function(e) {
    if ( e.target.nodeType.toLowerCase() === 'img' ) {
         // do stuff
    }
}, false);

for (i = 0; i < imga.length; i++) {
    imga[i].addEventListener("click", function() {
        for (i = 0; i < imga.length; i++) {
            img = document.createElement("img");
            img.setAttribute("src", imga[i].getAttribute("href"));
            lightbox.appendChild(img);
        }
    });
}

Issue 1

can be solved like above, with a delegated event handler

nav.addEventListener("click", function(e) {
    if ( e.target.nodeType.toLowerCase() === 'a' ) {

         // an achor was clicked, do stuff

    }
});
like image 88
adeneo Avatar answered Oct 27 '22 18:10

adeneo