删除函数无法通过ID删除元素

问题描述 投票:0回答:1

我正在学习 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>

javascript html
1个回答
0
投票

使用

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>

© www.soinside.com 2019 - 2024. All rights reserved.