首先我要说:
问题:删除按钮不会删除相应的内容,即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()
};
&#13;
<!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>
&#13;
答案 0 :(得分:0)
您正在绑定click事件侦听器以removeToDo,而removeToDo仅存在于renderUI函数内。所以你的第七步是错的。 你需要在createUI中添加Event监听器。用以下代码替换脚本
//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();
答案 1 :(得分:0)
您的代码中存在一些错误,我在下面使用注释对其进行了解释。 我已删除您的评论,以便您轻松找到我的
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()
};
&#13;
<!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>
&#13;
编辑 - 在性能方面更好的解决方案
//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()
};