Я пытаюсь разработать инструмент CRUD. Однако логика, которую я использую, чтобы преследовать это, проблематична. Вы можете найти мой полный JSFiddle по этой ссылке.

Мой HTML выглядит так:

<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>

Когда вы нажимаете remu, вы должны удалить соответствующий класс p. По какой-то причине щелкают последние remu ошибки. { { Х2 } } . Не уверен, почему это происходит.

Однако здесь есть еще одна проблема. То есть, когда я нажимаю generator, я хочу создать remu, который можно удалить, щелкнув по нему, во многом так же, как уже сгенерированные.

Проблема в том, что в какой-то момент сгенерированный remu перестает отвечать на мои клики. Мой вывод к этому заключается в том, что завершение моих функций внутри (function(i){//function here}(i)) только позволяет ему соответствовать тем функциям, которые уже присутствуют при создании DOM.

Это также имеет смысл, поскольку я использую протокол remove() для удаления из удаленных элементов DOM. Но мой сценарий действительно не очень хорошо работает.

Для справки мой код:

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 Фев 2018 в 04:21

5 ответов

Лучший ответ
  • Вам не нужен этот подход IIFE, просто свяжите событие click.
  • Используйте this.remove() вместо remu[i].remove(), чтобы избежать проблем с областью видимости 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 Фев 2018 в 01:29

Одна из проблем заключается в том, что когда вы вызываете removal() после добавления рыбы, вы не удаляете старых слушателей событий из элементов remu, которые были в исходном HTML. А когда вы удаляете элементы, их индексы в remu NodeList меняются. Таким образом, вы в конечном итоге удаляете несколько элементов с разными индексами.

Это не проблема для элементов moregohere, потому что использование innerHTML += воссоздает весь DOM в этом DIV, но на исходные элементы это не влияет.

Как указывает Ele, вы можете использовать this в прослушивателе событий для ссылки на элемент, по которому щелкнули, поэтому вам не нужно иметь дело с индексами. Но вы также должны удалить старого слушателя, чтобы он не запускался дважды. Использование именованной функции в качестве слушателя сделает это возможным.

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 Фев 2018 в 01:37

Когда вы удалите Fish 1, длина массива remu будет изменена. remu [3] (Fish 2) будет неопределенным. Пожалуйста, попробуйте код ниже. :)

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 Фев 2018 в 01:38

У вас есть серьезные проблемы с вашим текущим подходом.

Самоудаляющиеся элементы привязаны к их порядковому номеру, как было правильно при добавлении.

Но коллекция remu обновляется по мере добавления / удаления элементов. Таким образом, индексы не будут оставаться точными. Например, вы не можете удалить элемент, у которого изначально индекс был больше, чем у остальных!

Кроме того, вы присоединяете прослушиватель событий несколько раз - снова привязанный к индексу. Поэтому, если вы добавите новый элемент, который повторно связывает обработчики событий, а затем удалите первую Рыбу 0 (элемент 0), он дважды удалит элемент 0. То есть также удалите Рыбу 1. Добавьте 5 новых, а затем удалите предмет 0, и это займет еще 5 с ним!

Вам необходимо поддерживать состояние ваших объектов CRUD гораздо более безопасно, чем результат remu, а также избегать связывания с обработчиками более одного раза.

1
Raith 25 Фев 2018 в 01:38

Измените свой HTML так, чтобы ваш <div> содержал все элементы.

<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>

Есть более эффективный способ обработки элементов и привязки событий к объектам в DOM.

1
JokerDan 25 Фев 2018 в 01:32