Estoy intentando desarrollar una herramienta CRUD. Sin embargo, la lógica que estoy usando para perseguir esto es problemática. Puede encontrar mi JSFiddle completo en este enlace.

Mi HTML se ve así:

<p class="remu">Fish 0</p>
<p class="remu">Fish 1</p>
<p class="remu">Fish 2</p>
<div id="moregohere"></div>
<p id="generator">Generator</p>

Cuando hace clic en remu, debe eliminar la clase p correspondiente. Por alguna razón, haga clic en los últimos errores remu. cannot read property 'remove' of undefined. No estoy seguro de por qué está sucediendo.

Sin embargo, hay otro problema aquí. Es decir, cuando hago clic en generator, quiero generar un remu que se puede eliminar haciendo clic en él, de la misma manera que los ya generados.

El problema es que en algún momento el remu generado deja de responder a mis clics. Mi conclusión a esto es que envolver mis funciones dentro de (function(i){//function here}(i)) solo hace que corresponda a las funciones que ya están presentes en la creación de DOM.

Esto también tiene sentido ya que estoy usando el protocolo remove() para eliminar de los elementos DOM que he eliminado. Pero mi guión realmente no funciona muy bien.

Como referencia, mi código:

var remu = document.getElementsByClassName("remu");
var generator = document.getElementById("generator");
var moregohere = document.getElementById("moregohere");

generator.addEventListener('click', function() {
  moregohere.innerHTML += "<p class='remu'>Added Fish</p>";
  removal();
});

removal();

function removal() {
  for (i = 0; i < remu.length; i++) {
    (function(i) {
      remu[i].addEventListener('click', function() {
        remu[i].remove();
      });
    }(i));
  }
}
<p class="remu">Fish 0</p>
<p class="remu">Fish 1</p>
<p class="remu">Fish 2</p>
<div id="moregohere"></div>
<p id="generator">Generator</p>
0
Jason Chen 25 feb. 2018 a las 04:21

5 respuestas

La mejor respuesta
  • No necesita ese enfoque IIFE, solo enlace el evento click.
  • Use this.remove() en lugar de remu[i].remove() para evitar problemas de alcance variables i.
var remu = document.getElementsByClassName("remu");
var generator = document.getElementById("generator");
var moregohere = document.getElementById("moregohere");

generator.addEventListener('click', function() {
  moregohere.innerHTML += "<p class='remu'>Added Fish</p>";
  removal();
});

removal();

function removal() {
  for (var i = 0; i < remu.length; i++) {
    remu[i].addEventListener('click', function() {
      this.remove();
    });
  }
}
<p class="remu">Fish 0</p>
<p class="remu">Fish 1</p>
<p class="remu">Fish 2</p>
<div id="moregohere"></div>
<p id="generator">Generator</p>
2
Ele 25 feb. 2018 a las 01:29

Un problema es que cuando llama a removal() después de agregar un pez, no elimina los oyentes de eventos antiguos de los elementos remu que estaban en el HTML original. Y cuando elimina elementos, sus índices en la remu NodeList cambian. Entonces terminas eliminando múltiples elementos con diferentes índices.

Esto no es un problema para los elementos en moregohere, porque su uso de innerHTML += recrea todo el DOM en ese DIV, pero los elementos originales no se ven afectados.

Como señala Ele, puede usar this en el detector de eventos para referirse al elemento en el que se hizo clic, por lo que no necesita lidiar con los índices. Pero también debe eliminar el antiguo oyente para evitar que se ejecute dos veces. El uso de una función con nombre como oyente lo hará posible.

var remu = document.getElementsByClassName("remu");
var generator = document.getElementById("generator");
var moregohere = document.getElementById("moregohere");

generator.addEventListener('click', function() {
  moregohere.innerHTML += "<p class='remu'>Added Fish</p>";
  removal();
});

removal();

function removal() {
  for (i = 0; i < remu.length; i++) {
    remu[i].removeEventListener("click", removeThis);
    remu[i].addEventListener("click", removeThis);
  }
}

function removeThis() {
  this.remove();
}
<p class="remu">Fish 0</p>
<p class="remu">Fish 1</p>
<p class="remu">Fish 2</p>
<div id="moregohere"></div>
<p id="generator">Generator</p>
1
Barmar 25 feb. 2018 a las 01:37

Cuando elimine Fish 1, se cambiará la longitud de la matriz remota. remu [3] (Fish 2) estará indefinido. Por favor, intente el siguiente código. :)

var remu = document.getElementsByClassName("remu");
var generator = document.getElementById("generator");
var moregohere = document.getElementById("moregohere");

generator.addEventListener('click', function(){
	moregohere.innerHTML += "<p class='remu'>Added Fish</p>";
	removal();
});

removal();

function removal(){
	for (i = 0; i < remu.length; i++){
		const currentRemu = remu[i];
  		currentRemu.addEventListener('click', function(){
    		currentRemu.remove();
   	 });
  	
	}
}
<p class="remu">Fish 0</p>
<p class="remu">Fish 1</p>
<p class="remu">Fish 2</p>
<div id="moregohere"></div>
<p id="generator">Generator</p>
1
Kevin 25 feb. 2018 a las 01:38

Tiene algunos problemas masivos con su enfoque actual.

Los elementos autoextraíbles están vinculados a su número de índice, como era correcto cuando se agregaron.

Pero la colección remu se actualiza a medida que se agregan / eliminan elementos. Entonces los índices no serán precisos. ¡Por ejemplo, no puede eliminar un elemento que originalmente tenía un índice más alto que el número de los restantes!

Además, está adjuntando el detector de eventos varias veces, nuevamente vinculado al índice. Entonces, si agrega un nuevo elemento, que vuelve a vincular los controladores de eventos y luego elimina el primer Fish 0 (elemento 0), eliminará el elemento 0 dos veces. Es decir. también quite Fish 1. ¡Agregue 5 nuevos y luego quite el elemento 0 y se llevará otros 5 con él!

Debe mantener el estado de sus objetos CRUD de forma mucho más segura que el resultado remu, y también evitar los controladores de enlace más de una vez.

1
Raith 25 feb. 2018 a las 01:38

Cambie su HTML para que su <div> contenga todos los elementos.

<div id="moregohere">
  <p class="remu">Fish 0</p>
  <p class="remu">Fish 1</p>
  <p class="remu">Fish 2</p>
</div>
<p id="generator">Generator</p>

Hay una forma más efectiva de manejar elementos y vincular eventos a objetos en el DOM.

1
JokerDan 25 feb. 2018 a las 01:32