Estoy agregando los datos recibidos como resultado de una solicitud a mi página de la siguiente manera.
showMovieInfo(movies) { this.tableDiv.innerHTML = ""; movies.forEach(movie => { this.tableDiv.innerHTML += ` <table class="table align-middle mb-0 bg-white"> <thead class="bg-light"> <tr> <th>Movie Name</th> <th>Position</th> </tr> </thead> <tbody> <tr> <td> <div class="d-flex align-items-center"> <img src="${movie.image}" alt="" style="width: 120px; height: 120px" class="rounded-circle" /> <div class="ms-3"> <p class="fw-bold mb-1">${movie.title}</p> <p class="text-muted mb-0">${movie.description}</p> </div> </div> </td> <td> <button type="button" id="showonmap" class="btn btn-link btn-sm btn-rounded"> Show on map </button> </td> </tr> </tbody> </table>` }); }entonces quiero agregar addEventListener a los botones con id="showonmap". Pero recibo un error y cuando hago clic en los botones, ninguna función funciona.
Para respaldar el comentario realizado anteriormente con respecto al delegated event listener rápidamente hice esta demostración simple que reescribe ligeramente su método de clase original como una función independiente para que pueda ver el efecto en acción. Como el controlador de eventos se asigna a un elemento principal dentro del DOM que existe cuando se carga la página, puede usar el event para identificar en qué botón (u otro elemento) se hizo clic y desde allí realizar las operaciones necesarias.
const movies = [{ image: 'http://t1.gstatic.com/images?q=tbn:ANd9GcQsJW_I8KPZiq4mXcpRCd8uKBsUMR4Gz691k6gwEiLqVOoTl8pf', title: 'The Life of Brian', description: 'this is a great movie' }, { image: 'https://m.media-amazon.com/images/M/MV5BOTI4MDdjMmUtOTZhOS00MTYwLWEyZTUtYTdhMTQxNGM1YTUxXkEyXkFqcGdeQXVyMzg1ODEwNQ@@._V1_UX140_CR0,0,140,209_AL_.jpg', title: 'The Wasp Woman', description: 'this is a terrible movie' } ]; // slightly re-written as no longer part of a class/object showMovieInfo = (movies) => { // exlicitly define this.tableDiv here rather than in constructor earlier ( & not shown ) this.tableDiv = document.getElementById('movies'); this.tableDiv.innerHTML = ""; movies.forEach(movie => { this.tableDiv.innerHTML += ` <table class="table align-middle mb-0 bg-white"> <thead class="bg-light"> <tr> <th>Movie Name</th> <th>Position</th> </tr> </thead> <tbody> <tr> <td> <div class="d-flex align-items-center"> <img src="${movie.image}" alt="" style="width: 120px; height: 120px" class="rounded-circle" /> <div class="ms-3"> <p class="fw-bold mb-1">${movie.title}</p> <p class="text-muted mb-0">${movie.description}</p> </div> </div> </td> <td><!-- modified id to data-id and added data-title for demo --> <button type="button" data-id="showonmap" data-title="${movie.title}" class="btn btn-link btn-sm btn-rounded"> Show on map </button> </td> </tr> </tbody> </table>`; }); this.tableDiv.addEventListener('click', function(e) { if (e.target != e.currentTarget && e.target.tagName == 'BUTTON' && e.target.hasAttribute('data-id')) { alert(e.target.dataset.title); // ... here you would do other operations to actually "view on map" // ... etc } }) } showMovieInfo(movies); <div id='movies'></div>