簡體   English   中英

使用純JavaScript刪除待辦事項列表中的列表項

[英]Removing list item in to-do list using pure JavaScript

讓我首先說:

  1. 我已經看過很多有關解決此問題的文檔
  2. 我對JavaScript還是很陌生。

問題:刪除按鈕不會刪除對應的內容,這是一個li項目。 對我而言,這意味着問題出在步驟7的removeToDo.addEventListener或步驟8的function removeToDoItem ,但我可能是錯的。

 //2) SECOND STEP: build the function that will control everything function onReady() { //2.1) creates and houses the current state of to-do list var toDos = []; //3) THIRD STEP: Event Listener - this accesses the HTML form element var addToDoForm = document.getElementById('addToDoForm'); //2.2) build function that creates/adds list items function createNewToDo() { //2.3) accesses the text input from the form var newToDoText = document.getElementById('newToDoText'); //2.4) adds new item to the toDos array toDos.push({ title: newToDoText.value, complete: false }); //2.5) clears the text in the form input field so user doesn't need to newToDoText.value=''; renderTheUI(toDos); } //8) EIGHT STEP: build function that deletes list item function removeToDoItem() { newLi.toDoList.removeChild(newLi); renderTheUI(toDos); } //5) FIFTH STEP: build the function that will render the UI function renderTheUI(toDos) { //5.1) Accesses the <ul> in the HTML var toDoList = document.getElementById('toDoList'); //5.9 sets each newLi to an empty string toDoList.innerHTML = ''; //5.2) Use forEach() array method to render each to-do as an <li> in the <ul> toDos.forEach(function(toDo) { //5.3 creates new <li> var newLi = document.createElement('li'); newLi.setAttribute('id', 'myLi'); //5.4 creates new checkbox var checkbox = document.createElement('input'); //6) SIXTH STEP: create remove button and set its attributes var removeToDo = document.createElement('input'); removeToDo.setAttribute('type', 'button'); removeToDo.setAttribute('value', 'remove'); removeToDo.setAttribute('id', 'removeButton'); //5.5 set var checkbox as a type checkbox checkbox.type = 'checkbox'; //5.6 assigns to-do item to newLi in the HTML newLi.innerHTML = toDo.title; //5.7 appends newLi to the to-do list toDoList.appendChild(newLi); //5.8 appends a checkbox to each newLi newLi.appendChild(checkbox); //6.1 append the remove button to each newLi newLi.appendChild(removeToDo); }); } //3.1) Event Listener - catches 'submit', prevents page reload, // and invokes the function createNewToDo addToDoForm.addEventListener('submit', function(event) { event.preventDefault(); createNewToDo(); }); //7) SEVENTH STEP: assign remove button event and invoke removeToDoItem() removeToDo.addEventListener('click', function(event) { removeToDoItem(); }); //4) FOURTH STEP: add the call that controls UI based on state renderTheUI(toDos); } //1) FIRST STEP: invokes the function onReady() when page loads window.onload = function() { onReady() }; 
 <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>To-Do App</title> </head> <body> <h1>To-Do App</h1> <form id="addToDoForm"> <label for="newToDoText">New To-Do:</label> <input type="text" id="newToDoText"> <button type="submit">Add To-Do!</button> </form> <ul id="toDoList"> </ul> <script src="app.js"></script> </body> </html> 

您將單擊事件偵聽器綁定到removeToDo,而removeToDo僅存在於renderUI函數中。 因此,您的第七步是錯誤的。 您需要在createUI本身內部添加事件偵聽器。 用下面的代碼替換您的腳本

//2) SECOND STEP: build the function that will control everything
function onReady() {

  //2.1) creates and houses the current state of to-do list
  var toDos = [];

  //3) THIRD STEP: Event Listener - this accesses the HTML form element
  var addToDoForm = document.getElementById('addToDoForm');

  //2.2) build function that creates/adds list items
  function createNewToDo() {

    //2.3) accesses the text input from the form
    var newToDoText = document.getElementById('newToDoText');

    //2.4) adds new item to the toDos array
    toDos.push({
      title: newToDoText.value,
      complete: false
    });

    //2.5) clears the text in the form input field so user doesn't need to
    newToDoText.value='';

    renderTheUI(toDos);
  }

  //8) EIGHT STEP: build function that deletes list item
  function removeToDoItem(index) {
    console.log(toDos);
    toDos.splice(index, 1);
    console.log(toDos);
    renderTheUI(toDos);
  }

  //5) FIFTH STEP: build the function that will render the UI
  function renderTheUI(toDos) {

    //5.1) Accesses the <ul> in the HTML
    var toDoList = document.getElementById('toDoList');

    //5.9 sets each newLi to an empty string
    toDoList.innerHTML = '';

    //5.2) Use forEach() array method to render each to-do as an <li> in the <ul>
    toDos.forEach(function(toDo, index) {
            //5.3 creates new <li>
      var newLi = document.createElement('li');
      newLi.setAttribute('id', 'myLi');

      //5.4 creates new checkbox
      var checkbox = document.createElement('input');

      //6) SIXTH STEP: create remove button and set its attributes
      var removeToDo = document.createElement('input');
      removeToDo.setAttribute('type', 'button');
      removeToDo.setAttribute('value', 'remove');
      removeToDo.setAttribute('id', 'removeButton');
      removeToDo.setAttribute('class', 'removeButton');
      removeToDo.setAttribute('data-index', index);

      //5.5 set var checkbox as a type checkbox
      checkbox.type = 'checkbox';

      //5.6 assigns to-do item to newLi in the HTML
      newLi.innerHTML = toDo.title;

      //5.7 appends newLi to the to-do list
      toDoList.appendChild(newLi);

      //5.8 appends a checkbox to each newLi
      newLi.appendChild(checkbox);

      //6.1 append the remove button to each newLi
      newLi.appendChild(removeToDo);

      removeToDo.addEventListener('click', function(event) {
        removeToDoItem(index);
      });
    });
  }

  //3.1) Event Listener - catches 'submit', prevents page reload,
  // and invokes the function createNewToDo
  addToDoForm.addEventListener('submit', function(event) {
    event.preventDefault();
    createNewToDo();
  });

  //4) FOURTH STEP: add the call that controls UI based on state
  renderTheUI(toDos);
}
onReady();

您的代碼中有一些錯誤,我在下面使用注釋解釋了它們。 我刪除了您的評論,以便您輕松找到我的評論

function onReady() {
  var toDos = [];

  var addToDoForm = document.getElementById('addToDoForm');

  function createNewToDo() {

    var newToDoText = document.getElementById('newToDoText');

    toDos.push({
      title: newToDoText.value,
      complete: false
    });

    newToDoText.value='';
    renderTheUI(toDos);
  }

  function removeToDoItem() {
    // the parameters used here should be defined in any of the parent scopes of this function declaration
    // Example: Following variables are accessible inside this function
    // [toDos, renderTheUI] (created in parent scope of this function "onReady")
    // [onReady] (created in parent scope of onReady "window")
    // but newLi is not defined in any of the parent scopes. So, you should pass newLi as parameter to this function

    // newLi passed as parameter will not have a property toDoList
    newLi.toDoList.removeChild(newLi);
    renderTheUI(toDos);
  }

  function renderTheUI(toDos) {
    var toDoList = document.getElementById('toDoList');

    toDoList.innerHTML = '';

    toDos.forEach(function(toDo) {

      var newLi = document.createElement('li');
      newLi.setAttribute('id', 'myLi');

      var checkbox = document.createElement('input');

      var removeToDo = document.createElement('input');
      removeToDo.setAttribute('type', 'button');
      removeToDo.setAttribute('value', 'remove');
      removeToDo.setAttribute('id', 'removeButton');

      checkbox.type = 'checkbox';

      newLi.innerHTML = toDo.title;

      toDoList.appendChild(newLi);

      newLi.appendChild(checkbox);

      newLi.appendChild(removeToDo);
    });
  }


  addToDoForm.addEventListener('submit', function(event) {
    event.preventDefault();
    createNewToDo();
  });

  // Same as above, removeToDo is not accessible here as is it not defined in the parent scope
  removeToDo.addEventListener('click', function(event) {
    // Here you can access the element the click event is triggered on from "this"
    // You want to remove the "li" element that contains this button
    // You can get it from "this.parentElement", you can pass it to removeToDoItem
    removeToDoItem();
  });

  renderTheUI(toDos);
}
window.onload = function() {
  onReady()
};

我對您的代碼進行了更改,並修復了我上面提到的問題

解:

 //2) SECOND STEP: build the function that will control everything function onReady() { //2.1) creates and houses the current state of to-do list var toDos = []; //3) THIRD STEP: Event Listener - this accesses the HTML form element var addToDoForm = document.getElementById('addToDoForm'); //2.2) build function that creates/adds list items function createNewToDo() { //2.3) accesses the text input from the form var newToDoText = document.getElementById('newToDoText'); //2.4) adds new item to the toDos array toDos.push({ title: newToDoText.value, complete: false }); //2.5) clears the text in the form input field so user doesn't need to newToDoText.value=''; renderTheUI(toDos); } //8) EIGHT STEP: build function that deletes list item function removeToDoItem(newLi) { var toDoList = newLi.parentElement; // renderTheUI will render the same li again as it is still in the toDos array, you will have to remove the array entry // Get the index of the newLi inside it's parent var index = Array.prototype.indexOf.call(toDoList.children, newLi); // Remove the entry in toDos at that index, we are using same index as li's are the only elements inside toDos toDos.splice(index, 1); // Remove the li element now toDoList.removeChild(newLi); // No need to call the renderTheUI here as the li is already removed and the result would be same // renderTheUI(toDos); } //5) FIFTH STEP: build the function that will render the UI function renderTheUI(toDos) { //5.1) Accesses the <ul> in the HTML var toDoList = document.getElementById('toDoList'); //5.9 sets each newLi to an empty string toDoList.innerHTML = ''; //5.2) Use forEach() array method to render each to-do as an <li> in the <ul> toDos.forEach(function(toDo) { //5.3 creates new <li> var newLi = document.createElement('li'); newLi.setAttribute('id', 'myLi'); //5.4 creates new checkbox var checkbox = document.createElement('input'); //6) SIXTH STEP: create remove button and set its attributes var removeToDo = document.createElement('input'); removeToDo.setAttribute('type', 'button'); removeToDo.setAttribute('value', 'remove'); removeToDo.setAttribute('id', 'removeButton'); //7) SEVENTH STEP: assign remove button event and invoke removeToDoItem() removeToDo.addEventListener('click', function(event) { // You can access newLi here as it is decalred in the parent scope removeToDoItem(newLi); }); //5.5 set var checkbox as a type checkbox checkbox.type = 'checkbox'; //5.6 assigns to-do item to newLi in the HTML newLi.innerHTML = toDo.title; //5.7 appends newLi to the to-do list toDoList.appendChild(newLi); //5.8 appends a checkbox to each newLi newLi.appendChild(checkbox); //6.1 append the remove button to each newLi newLi.appendChild(removeToDo); }); } //3.1) Event Listener - catches 'submit', prevents page reload, // and invokes the function createNewToDo addToDoForm.addEventListener('submit', function(event) { event.preventDefault(); createNewToDo(); }); //4) FOURTH STEP: add the call that controls UI based on state renderTheUI(toDos); } //1) FIRST STEP: invokes the function onReady() when page loads window.onload = function() { onReady() }; 
 <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>To-Do App</title> </head> <body> <h1>To-Do App</h1> <form id="addToDoForm"> <label for="newToDoText">New To-Do:</label> <input type="text" id="newToDoText"> <button type="submit">Add To-Do!</button> </form> <ul id="toDoList"> </ul> <script src="app.js"></script> </body> </html> 

編輯-性能方面的更好解決方案

//2) SECOND STEP: build the function that will control everything
function onReady() {

  //2.1) creates and houses the current state of to-do list
  var toDos = [];

  //3) THIRD STEP: Event Listener - this accesses the HTML form element
  var addToDoForm = document.getElementById('addToDoForm');

  //2.2) build function that creates/adds list items
  function createNewToDo() {

    //2.3) accesses the text input from the form
    var newToDoText = document.getElementById('newToDoText');

    //2.4) adds new item to the toDos array
    toDos.push({
      title: newToDoText.value,
      complete: false
    });

    //2.5) clears the text in the form input field so user doesn't need to
    newToDoText.value='';

    renderTheUI(toDos);
  }

  //5) FIFTH STEP: build the function that will render the UI
  function renderTheUI(toDos) {

    //5.1) Accesses the <ul> in the HTML
    var toDoList = document.getElementById('toDoList');

    //5.9 sets each newLi to an empty string
    toDoList.innerHTML = '';

    //5.2) Use forEach() array method to render each to-do as an <li> in the <ul>
    toDos.forEach(function(toDo, index) {

      //5.3 creates new <li>
      var newLi = document.createElement('li');
      newLi.setAttribute('id', 'myLi');

      //5.4 creates new checkbox
      var checkbox = document.createElement('input');

      //6) SIXTH STEP: create remove button and set its attributes
      var removeToDo = document.createElement('input');
      removeToDo.setAttribute('type', 'button');
      removeToDo.setAttribute('value', 'remove');
      removeToDo.setAttribute('id', 'removeButton');

      //7) SEVENTH STEP: assign remove button event and invoke removeToDoItem()
      removeToDo.addEventListener('click', function() {
        // Remove the entry in toDos at the index
        toDos.splice(index, 1);
        // Remove the li element
        toDoList.removeChild(newLi);
      });

      //5.5 set var checkbox as a type checkbox
      checkbox.type = 'checkbox';

      //5.6 assigns to-do item to newLi in the HTML
      newLi.innerHTML = toDo.title;

      //5.7 appends newLi to the to-do list
      toDoList.appendChild(newLi);

      //5.8 appends a checkbox to each newLi
      newLi.appendChild(checkbox);

      //6.1 append the remove button to each newLi
      newLi.appendChild(removeToDo);
    });
  }

  //3.1) Event Listener - catches 'submit', prevents page reload,
  // and invokes the function createNewToDo
  addToDoForm.addEventListener('submit', function(event) {
    event.preventDefault();
    createNewToDo();
  });

  //4) FOURTH STEP: add the call that controls UI based on state
  renderTheUI(toDos);
}
//1) FIRST STEP: invokes the function onReady() when page loads
window.onload = function() {
  onReady()
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM