Вы смешиваете массив значений и список элементов в 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
, который необходимо удалить.
- так как вам не нужен массив, я удалил его