【问题标题】:How to delete a DOM element from an array after you've clicked on it?单击后如何从数组中删除 DOM 元素?
【发布时间】:2022-01-12 21:30:21
【问题描述】:

我正在制作一个简单的待办事项清单。您从输入提交项目,然后他们转到待办事项部分。当您单击它们时,它们会转到“完成”部分。当您再次单击它们时,它们将永远消失。一切正常。

但我意识到 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>

【问题讨论】:

    标签: javascript arrays dom onclick splice


    【解决方案1】:

    使用 JavaScript DOM API,例如 Node.removeChild()Element.remove()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>

    【讨论】:

      【解决方案2】:

      你会想要使用splice, 然后通过添加拼接数组中的所有元素,而不是使用隐藏,“刷新”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>

      【讨论】:

        猜你喜欢
        • 2021-05-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-12-19
        • 2020-10-08
        • 2015-01-29
        • 2012-09-29
        相关资源
        最近更新 更多