javascript: querySelectorAll no funciona con el elemento clonado

CorePress2024-01-24  9

Estoy intentando hacer una copia del div contenedor original con el método cloneNode en javascript dentro del contenedor hay 3 botones con clase btn, cuando hago una copia del original el último solo es el último elemento del El elemento copiado solo imprime Hola en la consola, ¿alguna idea?

let add = document.querySelector('.add-button');
const item = document.querySelector('.container');

let btn = document.querySelectorAll('.btn');

add.addEventListener('click', function() {
  makecopy();
});

btn.forEach(el => {
  el.addEventListener('click', function() {
    console.log("hello")

  })
});

function makecopy() {

  let copiedItem = item.cloneNode(true);
  item.parentNode.insertBefore(copiedItem, item);
}
<div class="add-panel">
  <button type="button" class="add-button">Create new</button>
</div>

<div class="container">
  <div>
    <button type="button" class="btn">+</button>
  </div>
  <div>
    <button type="button" class="btn">+</button>
  </div>
  <div>
    <button type="button" class="btn">+</button>
  </div>

¿Todo funcionó para mí? Sin embargo, tu problema es cuando creas otros nuevos.

-BGPHiJACK

26/03/2021 a las 18:57

cuando creas algo nuevo, los primeros 3 se imprimen ¿hola? , sí, exactamente, solo cuando creo uno nuevo y hago una copia del div original

Hamed

26/03/2021 a las 18:58

Bien, entonces, ¿lo que debes hacer es crear otro detector de eventos en cada copia? Esto le dará a cada botón su lista.ener.

-BGPHiJACK

26/03/2021 a las 18:59



------------------------------------

Solo estás configurando detectores de eventos en el primer conjunto de botones, no en los clonados. En lugar de configurar oyentes en cada botón, utilice la función de "delegación de eventos". para permitir que el evento "burbujee" hasta un ancestro común y manejar el evento allí. De esta manera, todos los elementos recién agregados funcionarán inmediatamente sin necesidad de su propio controlador y solo será necesario configurar un controlador en lugar de muchos.

También tienes código redundante y código que ya no será necesario cuando adoptes este enfoque.

// No need to set up an anonymous handler that calls the real one. Just
// register the real one
document.querySelector('.add-button').addEventListener('click', makecopy);
const item = document.querySelector('.container');

function makecopy() {
  let copiedItem = item.cloneNode(true);
  item.parentNode.insertBefore(copiedItem, item);
}

// Listen for clicks on the document:
document.addEventListener('click', function(event) {
  // Check to see if it was a button that was clicked:
  if(event.target.classList.contains("btn")){
    console.log("hello");
  };
});
<div class="add-panel">
  <button type="button" class="add-button">Create new</button>
</div>

<div class="container">
  <div>
    <button type="button" class="btn">+</button>
  </div>
  <div>
    <button type="button" class="btn">+</button>
  </div>
  <div>
    <button type="button" class="btn">+</button>
  </div>
</div>



------------------------------------

Simplemente parece que no estabas agregando nuevos oyentes cuando creaste nuevos botones. Algunos ajustes.

let add = document.querySelector('.add-button');
const item = document.querySelector('.container');

let btn = document.querySelectorAll('.btn');

add.addEventListener('click', function() {
  makecopy();
});

btn.forEach(el => {
  el.addEventListener('click', function() {
    console.log("hello")

  })
});

function makecopy() {

  let copiedItem = item.cloneNode(true);
  item.parentNode.insertBefore(copiedItem, item);
copiedItem.addEventListener('click', function() {
    console.log("hello")

  })
}
<div class="add-panel">
  <button type="button" class="add-button">Create new</button>
</div>

<div class="container">
  <div>
    <button type="button" class="btn">+</button>
  </div>
  <div>
    <button type="button" class="btn">+</button>
  </div>
  <div>
    <button type="button" class="btn">+</button>
  </div>

3

copiedItem en este caso puede hacer referencia a más de lo que desea, pero es un comienzo, tal vez crearía un nuevo elemento por clic y lo registraría luego, para facilitar, un bucledespués es fácil de implementar.

-BGPHiJACK

26/03/2021 a las 19:04

Gracias, pensé que querySelectorAll funciona para todas las clases, incluso la copiada.

Hamed

26/03/2021 a las 19:06

Cada vez que agregas más elementos que requieren querySelectorAll es necesario volver a llamarlos para contarlos todos. Sin embargo, si haces eso y los repites,puede configurar oyentes duplicados que obstaculizarán su aplicación. Así que encuentre un método apropiado para manejar esto y para mí sería crear y configurar un oyente con un punto de eliminación al iniciar cada cuadro. :)

-BGPHiJACK

26/03/2021 a las 19:09

Su guía para un futuro mejor - libreflare
Su guía para un futuro mejor - libreflare