单击数组后如何从数组中删除 DOM 元素?

How to delete a DOM element from an array after you've clicked on it?

我正在制作一个简单的待办事项列表。您从输入中提交 itens,然后它们会转到待办事项部分。当您点击它们时,它们会转到 'Done' 部分。当您再次单击它们时,它们将永远消失。一切正常。

但我意识到 doneItens 数组的长度一直在增长,我想对其进行优化。所以我想出了这行代码

        doneItens.splice(i, 1);

它进入 onclick 事件,您可以在 deleteDone 函数内的代码中看到它。

不过,这给出了错误,

Error:{
  "message": "Uncaught TypeError: doneItens.splice is not a function"

如果我将它放在 onclick 事件的外部和下方,它也不起作用。我该怎么做?

var input = document.getElementById('play');
var toDo = document.getElementsByTagName('ol')[0];
var done = document.getElementById('done');

function handleSubmit(event) {
    event.preventDefault();
    const newItem = document.createElement('li');
    newItem.setAttribute('class', 'item');
    newItem.append(input.value);
    toDo.append(newItem);
    input.value='';

    deleteItem();
}

function deleteItem() {
    const toBeDone = document.getElementsByClassName('item');
    for(let i = 0; i < toBeDone.length; i++) {
        toBeDone[i].onclick = () => {
            appendItemDone(toBeDone[i]);
            toBeDone[i].style.display = 'none';
            deleteDone();
        } 
    }   
}

function appendItemDone(item) {
        const newDone = document.createElement('li');
        newDone.setAttribute('class', 'feito')
        newDone.append(item.innerText);
        done.append(newDone);

}

function deleteDone() {
    const doneItens = document.getElementsByClassName('feito');
    console.log('done length', doneItens.length)
    for (let i = 0; i < doneItens.length; i++) {
        doneItens[i].onclick = () => {
            doneItens[i].style.display = 'none';
            doneItens.splice(i, 1);
        }
    }
}
<div id='flex'>
        <form class='form' onsubmit='handleSubmit(event)'>
            <input placeholder='New item' type='text' id='play'>
            <button>Send</button>
        </form>
        <div id='left'> 
            <h1 id='todo' >To-do:</h1>
            <p class='instruction'><i>(Click over to mark as done)</i></p>
            <ol id='here'></ol>
        </div>
    
        <div id='right'>
            <h1>Done:</h1>
      <p class='instruction'><i>(Click over to delete it)</i></p>
            <p id='placeholder'></p>
            <ol id='done'></ol>
        </div>
    </div>

您需要使用 splice, 然后不使用隐藏,'refresh' done 元素通过添加拼接数组中的所有元素。

我已经评论了我所做更改的代码以及原因

var input = document.getElementById('play');
var toDo = document.getElementsByTagName('ol')[0];
var done = document.getElementById('done');

function handleSubmit(event) {
    event.preventDefault();
    const newItem = document.createElement('li');
    newItem.setAttribute('class', 'item');
    newItem.append(input.value);
    toDo.append(newItem);
    input.value='';

    deleteItem();
}

function deleteItem() {
    const toBeDone = document.getElementsByClassName('item');
    for(let i = 0; i < toBeDone.length; i++) {
        toBeDone[i].onclick = () => {
            appendItemDone(toBeDone[i].cloneNode(true));
            toBeDone[i].style.display = 'none';
            deleteDone();
        } 
    }   
}

function appendItemDone(item) {
        const newDone = document.createElement('li');
        newDone.setAttribute('class', 'feito')
        newDone.append(item.innerText);
        done.append(newDone);

}

function deleteDone() {
    var doneItens = document.getElementsByClassName('feito');
    for (let i = 0; i < doneItens.length; i++) {
        doneItens[i].onclick = () => {
            var splicedArray = spliceFromArray(doneItens,doneItens[i]);// NEW BIT -CALL NEW SPLICE FUNCTION
            done.innerHTML=""; // NEW BIT - SET OVERALL DONE TO BLANK ON DELETE
            for(var index in  splicedArray){// NEW BIT - fOR EACH RETURNED ELEMENT IN THE SPLICE, ADD IT TO THE OVERALL DONE ELEMENT
              done.appendChild(splicedArray[index]); 
            }

            
        }
    }
}
function spliceFromArray(arrayInput,element){// NEW BIT - SPLICE FUNCTION THAT RETURNS SPLICED ARRAY
  var array = Array.from(arrayInput);
  var index = array.indexOf(element);
  if(index!=-1){
    if(array.length==1 && index == 0){
      array = [];
    }
    else{
      array.splice(index,1);
    }
  }
  return array;
  
}
<div id='flex'>
        <form class='form' onsubmit='handleSubmit(event)'>
            <input placeholder='New item' type='text' id='play'>
            <button>Send</button>
        </form>
        <div id='left'> 
            <h1 id='todo' >To-do:</h1>
            <p class='instruction'><i>(Click over to mark as done)</i></p>
            <ol id='here'></ol>
        </div>
    
        <div id='right'>
            <h1>Done:</h1>
      <p class='instruction'><i>(Click over to delete it)</i></p>
            <p id='placeholder'></p>
            <ol id='done'></ol>
        </div>
    </div>

使用JavaScript DOM API 例如Node.removeChild(), Element.remove() and Node.parentNode,你的任务可以用这个代码解决:

const input = document.getElementById('play');
const todo = document.getElementById('todo');
const done = document.getElementById('done');

function handleSubmit(event) {
  event.preventDefault();

  // create new "todo" item
  const newTodo = document.createElement('li');
  newTodo.textContent = input.value;
  todo.append(newTodo);

  // clean the input field
  input.value = '';

  // listen to "click" event on the created item to move it to "done" section
  newTodo.addEventListener('click', moveToDone);
}

function moveToDone(event) {
  // remove "click"-listener to prevent event listener leaks
  event.target.removeEventListener('click', moveToDone);

  // move clicked todo-element to "done" section
  const newDone = event.target.parentNode.removeChild(event.target);
  done.append(newDone);

  // listen to "click" event on the moved item to then completely delete it
  newDone.addEventListener('click', removeFromDone);

  debugElementsLeak();
}

function removeFromDone(event) {
  // remove "click"-listener to prevent event listener leaks
  event.target.removeEventListener('click', removeFromDone);

  // complete remove clicked element from the DOM
  event.target.remove();

  debugElementsLeak();
}

function debugElementsLeak() {
  const todoCount = todo.childElementCount;
  const doneCount = done.childElementCount;
  console.log({ todoCount, doneCount });
}
<div id="flex">
  <form class="form" onsubmit="handleSubmit(event)">
    <input placeholder="New item" type="text" id="play">
    <button>Add item</button>
  </form>

  <div id="left">
    <h1>To-do:</h1>
    <p class="instruction"><em>(Click over to mark as done)</em></p>
    <ol id="todo"></ol>
  </div>

  <div id="right">
    <h1>Done:</h1>
    <p class="instruction"><em>(Click over to delete it)</em></p>
    <p id="placeholder"></p>
    <ol id="done"></ol>
  </div>
</div>