我正在学习 js,为了练习我所学的知识,我正在构建一个待办事项列表。它有一个删除按钮,用于删除列表项。它通过我使用增量自动生成的 ID 来删除元素。但是,它会删除所有元素,无论其 id 为何,然后抛出 null 错误。
我花了将近2个小时来解决这个问题,尝试了每种方法。如果您能帮助我,我将不胜感激。
let store = [];
let store_len = -1;
let auto_id = 0
function fetchList() {
store_len++;
let user_input = document.querySelector(".input").value;
let date_input = document.querySelector(".date").value
store[store_len] = {
TODO: user_input,
Date: date_input
};
document.querySelector(".div").innerHTML = ''
for (let i = 0; i < store.length; i++) {
auto_id++;
html = `<div id="${auto_id}">${store[i].TODO}</div>
<div id="${auto_id}">${store[i].Date}</div>
<button id="${auto_id}" onclick='
store.splice(${i}, 1);
document.querySelector(".grid").innerHTML = "";
store_len--;
document.getElementById("${auto_id}").remove();
'>Delete</button>`
document.querySelector(".div").innerHTML += html
};
};
<!DOCTYPE html>
<html>
<body>
<head>
<style>
.grid {
display: grid;
grid-template-columns: 15% 10% 5%;
}
</style>
</head>
<p>Todo list</p>
<input class="input" placeholder="Todo name">
<input type="date" class="date">
<button onclick="fetchList();">Add</button>
<div class="div grid"></div>
<script src="TODOjs.js"></script>
</body>
</html>
使用
document.querySelector(".grid").innerHTML = ""
可以清除列表。删除发生后,没有代码可以重新填充页面上的列表。此外,当您清除网格时,document.getElementById("${auto_id}")
将尝试访问不再存在的 DOM 元素。
其他一些评论:
不要将脚本放入
onclick
属性中。这是不好的做法。相反,使用该逻辑创建一个函数,然后调用该函数
通过代码而不是通过
onclick
属性附加事件处理程序也是更好的做法。
声明您的变量,例如
html
与 const
、let
或 var
,否则它们将隐式声明为全局变量。
i
通常不再是被删除元素的索引,因为您可能已经删除了它之前的其他元素,这意味着它的索引已经减少。您需要一种不同的方式来识别要删除的项目的索引。一种方法是在每次删除后始终重新显示整个列表(就像每次添加时所做的那样)。
为每个按钮使用唯一的
id
并不是最佳实践。通过使用 addEventListener
将事件处理程序附加到删除按钮,您可以使用 i
的值,而无需任何 HTML 属性。
CSS 网格很好,但是当您减小浏览器的宽度时,列宽的百分比将无法正常工作。最好使用
max-content
来确定网格列的宽度。
这是一个可能的实现:
const store = [];
// Get all DOM element references
const todoNameInput = document.querySelector(".input");
const todoDateInput = document.querySelector(".date");
const addButton = document.querySelector(".action");
const container = document.querySelector(".grid");
// Bind event handlers via code only
addButton.addEventListener("click", () => {
store.push({ todo: todoNameInput.value, date: todoDateInput.value });
// Separate the logic for the display in a function
displayList();
});
function displayList() {
container.innerHTML = ''
for (let i = 0; i < store.length; i++) {
const elemName = document.createElement("div");
const elemDate = document.createElement("div");
const delButton = document.createElement("button");
elemName.textContent = store[i].todo;
elemDate.textContent = store[i].date;
delButton.textContent = "Delete";
// Bind event handlers via code
delButton.addEventListener("click", () => {
store.splice(i, 1); // We have the index!
displayList(); // Re-display the whole list
});
container.append(elemName);
container.append(elemDate);
container.append(delButton);
}
}
.grid {
display: grid;
grid-template-columns: max-content max-content max-content ;
}
.grid div {
padding: 5px;
}
<p>Todo list</p>
<input class="input" placeholder="Todo name">
<input type="date" class="date">
<button class="action">Add</button>
<div class="grid"></div>