Tengo una lista <ul> con algunos elementos <li> dentro, y he agregado un detector de eventos de click para cada uno de estos elementos para mover el elemento en el que se hizo clic a la parte superior de la lista.
function add_event_listeners() { let elements = my_list.getElementsByTagName('li'); for (let item of elements) { item.addEventListener("click", send_to_top); } } function send_to_top() { this.parentElement.children[0].insertAdjacentElement('beforebegin', this); } Este código funciona bien hasta que elimino o agrego un nuevo li a la lista, todos los detectores de eventos se eliminan y los clics posteriores no funcionan.
¿Cuál es el detector de eventos adecuado para detectar que se ha agregado o eliminado un nuevo elemento de la lista? Entonces, ¿puedo usarlo para ejecutar la función add_event_listeners() después de eso?
Basado en la documentación deHTMLCollection en MDN:
Una
HTMLCollectionen HTML DOM está activa; se actualiza automáticamente cuando se cambia el documento subyacente. Por esta razón, es una buena idea hacer una copia (p. ej., usandoArray.from) para iterar si agrega, mueve o elimina nodos.
¿Alguien puede ayudar con un ejemplo de código de cómo hacer eso?
De alguna manera, el mío funciona simplemente refactorizando el código, vea a continuación:
<html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> </head> <body> <ul id="lists"> <li class="list-item"> <div>List #1</div> <button class="btn-send-up">Send to top</button> </li> <li class="list-item"> <div>List #2</div> <button class="btn-send-up">Send to top</button> </li> <li class="list-item"> <div>List #3</div> <button class="btn-send-up">Send to top</button> </li> <li class="list-item"> <div>List #4</div> <button class="btn-send-up">Send to top</button> </li> </ul> <script> const listsEl = document.getElementById('lists'); const addEventListeners = () => { const sendUpBtnEls = document.querySelectorAll('.btn-send-up'); sendUpBtnEls.forEach((sendUpBtnEl) => { sendUpBtnEl.addEventListener('click', (e) => { const listItemEl = e.target.closest('.list-item'); listsEl.firstElementChild.insertAdjacentElement( 'beforebegin', listItemEl, ); }); }); }; addEventListeners(); </script> </body> </html>Estaba evitando usar MutationObserver para capturar cualquier cambio en el HTML de la lista porque pensé que sería complicado y consumiría mucho rendimiento.
Pude manejar eso usando este código:
const observer = new MutationObserver( () => authors_list__add_listeners() ); observer.observe(my_list, { childList: true });