JavaScript issues regarding dynamically generated HTML events

I have some problems targeting dynamically created elements with JavaScript.

Problem 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 to get an event to target #lightbox nav a instead of #lightbox nav ?

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

I have tried many things, for example:

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

Problem 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 to add an event to dynamically generated #lightbox img ? img = document.createElement("img") must be inside the function to add multiple images, and for this reason I cannot do this (for example, currently on <nav> ):

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

Can someone please help me with this? I am not very good at JavaScript.

+5
source share
2 answers

In my case, the decision was not too complicated. Since @adeneo made me think about nesting event handlers, it turned out that everything worked fine, and I was able to use all my selectors without changes:

 var lightbox = document.createElement('div'), nav = document.createElement("nav"), imga = document.querySelectorAll(".gallery a"), gallery = document.getElementsByClassName("gallery"), img; for (i = 0; i < imga.length; i++) { imga[i].addEventListener("click", function() { lightbox.appendChild(nav); document.body.insertBefore(lightbox, document.body.firstChild); for (i = 0; i < imga.length; i++) { img = document.createElement("img"); lightbox.appendChild(img); } lightbox.addEventListener("click", function() { // works fine }); var nava = document.querySelectorAll("#lightbox nav a"); for (i = 0; i < nava.length; i++) { nava[i].addEventListener("click", function() { // works fine }); } var limg = document.querySelectorAll("#lightbox img"); for (i = 0; i < limg.length; i++) { limg[i].addEventListener("click", function() { // works fine }); } }); } 
0
source

Problem 2

A simple solution is to add an event handler to all elements within 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); } }); } 

a slightly more complicated 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); } }); } 

Problem 1

can be resolved as described above using a delegated event handler

 nav.addEventListener("click", function(e) { if ( e.target.nodeType.toLowerCase() === 'a' ) { // an achor was clicked, do stuff } }); 
+3
source

Source: https://habr.com/ru/post/1209934/


All Articles