如何使用拼接从 HTML 待办事项列表中删除 DOM 元素
how to remove DOM element from HTML to-do list using splice
我正在尝试实施拼接方法以从 JavaScript 待办事项列表中删除项目。使用我当前的代码,当单击删除按钮时,一个项目将从列表中清楚地删除。
但是,单击删除按钮也会将列表转换为带有默认逗号的简单数组。关于如何使用 splice 方法正确设置删除功能有什么建议吗?
非常感谢!
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>
您混淆了 值数组 和 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)
,其中 according to the docs 表示:
- 您正在更新阵列
- 您要删除从索引 1 开始的 1 个元素
基本上每次调用 remove()
时都会删除数组中的第二项。绝对不是你想要的
此外,您将字符串数组设置为 div 的 innerHTML
:
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
,这允许您使用闭包。
- 使用 closure 而不是数组,这允许事件处理程序引用需要删除的
li
。
- 由于您不需要数组,我已将其删除
我正在尝试实施拼接方法以从 JavaScript 待办事项列表中删除项目。使用我当前的代码,当单击删除按钮时,一个项目将从列表中清楚地删除。
但是,单击删除按钮也会将列表转换为带有默认逗号的简单数组。关于如何使用 splice 方法正确设置删除功能有什么建议吗?
非常感谢!
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>
您混淆了 值数组 和 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)
,其中 according to the docs 表示:
- 您正在更新阵列
- 您要删除从索引 1 开始的 1 个元素
基本上每次调用 remove()
时都会删除数组中的第二项。绝对不是你想要的
此外,您将字符串数组设置为 div 的 innerHTML
:
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
,这允许您使用闭包。 - 使用 closure 而不是数组,这允许事件处理程序引用需要删除的
li
。 - 由于您不需要数组,我已将其删除