简体   繁体   English

无法移除 li 元素

[英]can't remove li element

I'm trying to create a to-do list app.我正在尝试创建一个待办事项列表应用程序。

I'm able to add li elements (ie user tasks) when clicking on the '+' button.单击“+”按钮时,我可以添加li元素(即用户任务)。

However, I'd like to remove li elements when clicking on them.但是,我想在单击li元素时删除它们。 But when I click on a li element or task added by a user nothing happens.但是当我点击用户添加的li元素或任务时,什么也没有发生。

 function dark() { // setting up dark-mode var element = document.body; element.classList.toggle("dark-mode"); //dark-mode class } let addToDoButton = document.getElementById('addToDo'); let toDoContainer = document.getElementById('newTask'); let inputField = document.getElementById('tasks'); let removeButton = document.getElementById('remove'); addToDoButton.addEventListener('click', function() { var input = document.createElement('li') input.classList.add('tasks') input.innerText = inputField.value; toDoContainer.appendChild(input); inputField.value = '\n'; //input.style.textDecoration = "line-through"; }) input.addEventListener('click', function() { // input.style.textDecoration = "line-through"; toDoContainer.removeChild(input); inputField.value = " "; //const task = document.getElementById("remove"); //task.innerHTML = " "; })
 <body id="dark-mode"> <div class="container"> <div class="toggle"> <label class="switch"> <input type="checkbox"onclick="dark()" checked> <span class="slider round">&#9728;</span> </label> </div> <div class="title"> <h1>Today I will ...</h1> </div> <br> <div class="tasks" id="newTask"> <input class="new" id="tasks" type="text" placeholder="Task to be completed..."> <br> <button id="addToDo">+</button><br> </div> </div> <div class="added"> <ul> <!--tasks show here--> </ul> </div>

the input variable is not known in the global scope. input变量在全局范围内未知。 I would recommend doing event delegation from a static parent using the event object.我建议使用事件对象从静态父级进行事件委托

 function dark() { // setting up dark-mode var element = document.body; element.classList.toggle("dark-mode"); //dark-mode class } let addToDoButton = document.getElementById('addToDo'); let toDoContainer = document.getElementById('newTask'); let inputField = document.getElementById('tasks'); let removeButton = document.getElementById('remove'); addToDoButton.addEventListener('click', function() { var input = document.createElement('li') input.classList.add('tasks') input.innerText = inputField.value; toDoContainer.appendChild(input); inputField.value = '\n'; }) toDoContainer.addEventListener('click', function(event) { if([...toDoContainer.querySelectorAll('li.tasks')].includes(event.target)) { toDoContainer.removeChild(event.target); } })
 <body id="dark-mode"> <div class="container"> <div class="toggle"> <label class="switch"> <input type="checkbox"onclick="dark()" checked> <span class="slider round">&#9728;</span> </label> </div> <div class="title"> <h1>Today I will ...</h1> </div> <br> <div class="tasks" id="newTask"> <input class="new" id="tasks" type="text" placeholder="Task to be completed..."> <br> <button id="addToDo">+</button><br> </div> </div> <div class="added"> <ul> <!--tasks show here--> </ul> </div>

The following lines are a problem:以下几行是一个问题:

let toDoContainer = document.getElementById('newTask');
//...
toDoContainer.appendChild(input);

#newTask is a <div> that wraps around all of the ToDo list interface. #newTask是一个<div> ,它包裹了所有的 ToDo 列表界面。 So all of the <li> ended up below the <button> -- not in it's intended place within the <ul> .所以所有的<li>都在<button>下方——而不是在<ul>中的预期位置。

<div class="container">
<!-- Other HTML -->
  <div class="tasks" id="newTask">
    <input class="new" id="tasks" type="text" placeholder="Task to be completed..."> <br>
    <button id="addToDo">+</button><br>

      <!-- All <li> was appended here -->

  </div><!-- End of #newTask -->
</div><!-- End of .container -->
<div class="added">
  <ul>
    <!--tasks show here-->
  </ul>
</div>

Another problem is:另一个问题是:

input.addEventListener('click', function() {//...

The only time input was defined was within the first event handler.唯一一次定义input是在第一个事件处理程序中。 Since it was never declared or defined outside of that event handler, it is out of scope.由于它从未在该事件处理程序之外声明或定义,因此它超出了范围。 There are few reasons why just moving input outside of the event handler wouldn't work as well.input移到事件处理程序之外并不能正常工作的原因很少。

  • input is dynamically created within the event handler so it can't be defined anywhere else although it can be declared, thus bringing it into scope, but... input是在事件处理程序中动态创建的,因此尽管可以声明它,但不能在其他任何地方定义它,从而将其纳入范围,但是......

  • input is pointing to document.createElement('li') making that particular reference pointing to a unique object. input指向document.createElement('li')使该特定引用指向唯一对象。 So at best you can bind each <li> to the click event as they are being created.因此,充其量您可以将每个<li>在创建时绑定到单击事件。 Not that good, but possible, but I never tested it cause it's just too messy.不是那么好,但可能,但我从未测试过它,因为它太乱了。

The best solution is to bind the click event to the <ul> then you never have to worry about keeping track of <li> , see event delegation for details.最好的解决方案是将点击事件绑定到<ul> ,然后您就不必担心跟踪<li> ,请参阅事件委托了解详细信息。

The example is a strpped down version of the OP.该示例是 OP 的精简版。 As long as you're careful about renaming anything in this code (if you actually want to that is), there shouldn't be any problems with adding the rest of the HTML back in.只要您小心重命名此代码中的任何内容(如果您真的想要这样做的话),重新添加 HTML 的其余部分应该不会有任何问题。

Details on the removal part is commented in the example示例中注释了移除部分的详细信息

 const add = document.getElementById('add'); const text = document.getElementById('text'); const list = document.querySelector('ul'); add.addEventListener('click', function() { const task = document.createElement('li') task.classList.add('tasks') task.innerText = text.value; list.appendChild(task); text.value = ''; }) // Bind click event to <ul> list.addEventListener('click', removeItem); function removeItem(e) { // If the user clicked a <li>... if (e.target.matches('li')) { // ... remove that <li> e.target.remove(); } }
 <input id="text" type="text" placeholder="Task to be completed..."> <button id="add">+</button><br> <ul> <!--tasks show here--> </ul>

请使用 visibility='none' 或使用 javascript 隐藏此元素

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM