как удалить элемент DOM из списка дел HTML, используя сплайс - PullRequest
0 голосов
/ 12 ноября 2018

Я пытаюсь реализовать метод соединения для удаления элементов из списка задач JavaScript. В моем текущем коде элемент четко удаляется из списка при нажатии кнопки удаления.

Однако, щелкая кнопку удаления, также появляется, чтобы преобразовать список в простой массив с запятыми по умолчанию. Есть ли какие-либо рекомендации о том, как правильно настроить функцию удаления с помощью метода сплайсинга?

Очень ценится!

var array = [];

function add() {
  var task = document.getElementById("task").value;
  array.push(task);
  var text = document.createTextNode(task);
  var li = document.createElement("li");
  var btn = document.createElement("button");
  btn.appendChild(document.createTextNode("x"));
  btn.setAttribute("onclick", 'remove()');
  li.appendChild(text);
  li.appendChild(btn);
  document.getElementById("myUl").appendChild(li);
}

function remove() {
  array.splice(1, 1);
  document.getElementById("myUl").innerHTML = array;
}
<input id="task">
<button onclick="add()">add</button>
<ul id="myUl"></ul>

1 Ответ

0 голосов
/ 12 ноября 2018

Вы смешиваете массив значений и список элементов в DOM . Ваш массив содержит список текстовых значений задач:

var task = document.getElementById("task").value;
array.push(task);

Это просто список строк из входного значения, но он не связан со списком элементов на вашей странице.

Когда вы пытаетесь удалить задачу:

function remove() {
  array.splice(1, 1);
  document.getElementById("myUl").innerHTML = array;
}

Вы используете array.splice(1,1), что в соответствии с документами означает:

  • вы обновляете свой массив
  • вы удаляете 1 элемент, начиная с индекса 1

Обычно каждый раз, когда вы вызываете remove(), вы удаляете второй элемент в массиве. Определенно не то, что вы хотите.

Кроме того, вы устанавливаете массив строк как innerHTML элемента div:

document.getElementById("myUl").innerHTML = array;

Это, по существу, заменяет все содержимое вашего ul списком строк, которое вы наблюдаете. Здесь вы хотите удалить соответствующий элемент из DOM.

Если вы хотите сохранить массив задач одновременно, у вас есть несколько вариантов. Вы можете сохранить массив со списком задач, это будет копия добавленных задач, и вам нужно будет поддерживать этот список вместе с вашими элементами HTML. Ведение двух копий вашего списка задач не является надежным , потому что вам нужно обновлять их вручную, поэтому было бы безопаснее извлечь один из списков из другого:

  • при необходимости создайте массив задач из элементов в dom
  • пусть ваша функция обновит ваш массив и сгенерирует из него ваши DOM-элементы.

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

Вот рабочий пример, где я использую элементы DOM, чтобы получить текущий список задач:

function getTasks() {
  return Array.from(document.querySelectorAll('li')).map(l => l.dataset.taskName);
}

function onAddTaskClick() {
 addTask(document.getElementById("task").value);
 console.log(getTasks());
}

function addTask(task) {
  const text = document.createTextNode(task);
  const li = document.createElement("li");
  li.dataset.taskName = task;
  const btn = document.createElement("button");
  btn.appendChild(document.createTextNode("x"));
  // Instead of maintaining an array of elements and using splice,
  // you can use a closure to add an event listener that will remove 
  // itself from the DOM.
  btn.addEventListener('click', () => {
    li.remove();
    console.log(getTasks());
  });
  li.appendChild(text);
  li.appendChild(btn);
  document.getElementById("myUl").appendChild(li);
}

addTask('sampleTask1');
addTask('sampleTask2');
addTask('sampleTask3');
console.log(getTasks());
<input id="task">
<button onclick="onAddTaskClick()">add</button>
<ul id="myUl"></ul>

Несколько изменений, которые я внес в код:

  • использовал const для любых переменных, которые не были переназначены.
  • используется addEventListener вместо onclick, что позволяет использовать замыкание.
  • использовал замыкание вместо массива, что позволяет обработчику событий иметь ссылку на li, который необходимо удалить.
  • так как вам не нужен массив, я удалил его
...