[英]Removing list item in to-do list using pure 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.