我已经在watchandcode.com课程之后创建了一个todo-list,我试图为它添加更多功能。所以我想制作一个COMPLETED按钮,用于切换已完成的未完成列表项,在点击它之后以及将列表项变为已完成之后DISAPPEAR。我希望我能够正确地表达自己想要达到的目标。这是下面的代码,提前谢谢! 我在下面复制了整个代码,但是如果你只需要查看我可能会引用的部分(我不确定,因为我真的是JS的新手),这里它们是:
var view = {
displayTodos: function(){
var todosUl = document.querySelector("ul");
todosUl.innerHTML = '';
for (var i = 0; i < todoList.todos.length; i++){
var todoLi = document.createElement("li");
var todo = todoList.todos[i];
var todoTextForCompleted = "";
if (todo.completed === true){
todoTextForCompleted = todo.todoText;
todoLi.classList.toggle("checked");
} else {
todoTextForCompleted = todo.todoText;
todoLi.classList.toggle("notCompleted");
}
todoLi.id = i;
todoLi.textContent = todoTextForCompleted;
todoLi.appendChild(this.createDeleteButton());
todoLi.appendChild(this.createToggleButton());
todosUl.appendChild(todoLi);
}
},
createToggleButton: function(){
var toggleButton = document.createElement("button");
toggleButton.textContent = "Completed";
toggleButton.id= "toggleBtn";
return toggleButton;
},
如果有必要,这是完整的代码:
//The object that holds the todo list:
var todoList = {
todos: [],
//Method for ADDING a TODO items
addTodo: function(todoText){
this.todos.push({
todoText: todoText,
completed: false,
});
},
//Method for changing the made TODO items
changeTodo: function(position, newValue){
this.todos[position].todoText = newValue;
},
//Method for deleting TODO items:
deleteTodo: function(position){
this.todos.splice(position, 1);
},
//Method for toggling a todo item as COMPLETED:
toggleCompleted: function(position){
var todo = this.todos[position];
todo.completed = !todo.completed;
},
//Method for toggling ALL todo items:
toggleAll: function(){
var totalTodos = this.todos.length;
//Counting the ones that are completed
var completedTodos = 0;
//Getting the number of the completed todos:
for(var i = 0; i < totalTodos; i++){
if(this.todos[i].completed === true) {
//For every todo item that is completed, increase completedTodos by 1;
completedTodos++;
}
}
//Case 1: If everything is true, the turn it into FALSE;
if(completedTodos === totalTodos){
for(var i = 0; i < totalTodos; i++){
this.todos[i].completed = false
}
//Case 2: Otherwise, make everything TRUE;
} else {
for (var i = 0; i < totalTodos; i++){
this.todos[i].completed = true;
};
};
}
}
//Object for the BUTTON HANDLERS:
var handlers = {
addTodo: function(){
var addTodoText = document.getElementById("addTodoTextInput");
todoList.addTodo(addTodoTextInput.value);
//Clear the input
addTodoText.value = "";
view.displayTodos();
},
//Change todo
changeTodo: function(){
var changeTodoText = document.getElementById("changeTodoText");
var changeTodoPosition = document.getElementById("changeTodoPosition");
//Get the CHANGE TODO method in the object TODOLIST and set these parameters
todoList.changeTodo(changeTodoPosition.valueAsNumber, changeTodoText.value);
//Clear the inputs
changeTodoText.value = "";
changeTodoPosition.value = "";
//Call upon VIEW object and trigger displayTodos() method/function;
view.displayTodos();
},
deleteTodo: function(position){
todoList.deleteTodo(position);
view.displayTodos();
},
deleteAll:function(position){
todoList.todos.splice(position);
view.displayTodos();
},
toggleCompleted: function(){
var toggleCompletedInput = document.getElementById("toggleBtn");
todoList.toggleCompleted(toggleCompletedInput.valueAsNumber);
toggleCompletedInput.value = "";
view.displayTodos();
},
toggleAll: function(){
todoList.toggleAll();
view.displayTodos();
}
};
//Object that is used only to DISPLAY the items:
var view = {
displayTodos: function(){
var todosUl = document.querySelector("ul");
todosUl.innerHTML = '';
for (var i = 0; i < todoList.todos.length; i++){
var todoLi = document.createElement("li");
var todo = todoList.todos[i];
var todoTextForCompleted = "";
if (todo.completed === true){
todoTextForCompleted = todo.todoText;
todoLi.classList.toggle("checked");
} else {
todoTextForCompleted = todo.todoText;
todoLi.classList.toggle("notCompleted");
}
todoLi.id = i;
todoLi.textContent = todoTextForCompleted;
todoLi.appendChild(this.createDeleteButton());
todoLi.appendChild(this.createToggleButton());
todosUl.appendChild(todoLi);
}
},
createDeleteButton: function(){
var deleteButton = document.createElement("button");
deleteButton.textContent = "DELETE";
deleteButton.className = "deleteBtn";
return deleteButton;
},
createToggleButton: function(){
var toggleButton = document.createElement("button");
toggleButton.textContent = "Completed";
toggleButton.id= "toggleBtn";
return toggleButton;
},
//
setUpEventListeners: function(){
var todosUl = document.querySelector("ul");
todosUl.addEventListener("click", function(event){
var elementClicked = event.target;
if(elementClicked.className === "deleteBtn"){
handlers.deleteTodo(parseInt(elementClicked.parentNode.id));
}
if (elementClicked.id === "toggleBtn"){
todoList.toggleCompleted(parseInt(elementClicked.parentNode.id));
var toggleCompletedInput = document.getElementById("toggleBtn");
toggleCompletedInput.value = "";
view.displayTodos();
view.removeTodoButton();
}
});
}
}
view.setUpEventListeners();
答案 0 :(得分:1)
代码有点混乱......我看到的主要问题是你使用了具有相同id(toggleBtn
)的多个元素。我将其更改为使用className。这里有一个遵循设计模式的工作版本(视图模型处理程序)。
变化是:
toggleCompleted: function(position) {
var toggleCompletedInput = document.querySelector("#" + position + " toggleBtn");
var todoLi = document.createElement("li");
var todo = todoList.todos[i];
todoLi.id = i;
todoLi.textContent = todo.todoText;
if (todo.completed === true) {
todoLi.classList.toggle("checked");
} else {
todoLi.classList.toggle("notCompleted");
todoLi.appendChild(this.createToggleButton());
}
todoLi.appendChild(this.createDeleteButton());
todosUl.appendChild(todoLi);
toggleButton.className = "toggleBtn";
if (elementClicked.className === "toggleBtn") {
todoList.toggleCompleted(parseInt(elementClicked.parentNode.id));
view.displayTodos();
}
在CSS中:
.toggleBtn {
background-color: #eee;
color: #e84118;
cursor: pointer;
position: absolute;
right: 70px;
bottom: 3px;
animation: delete 0.5s ease-out 1 forwards;
}
.toggleBtn:hover {
background-color: #4cd137;
color: #eee;
}
.toggleBtn.removed {
display: none;
}
//The object that holds the todo list:
var todoList = {
todos: [],
//Method for ADDING a TODO items
addTodo: function(todoText) {
this.todos.push({
todoText: todoText,
completed: false,
});
},
//Method for changing the made TODO items
changeTodo: function(position, newValue) {
this.todos[position].todoText = newValue;
},
//Method for deleting TODO items:
deleteTodo: function(position) {
this.todos.splice(position, 1);
},
//Method for toggling a todo item as COMPLETED:
toggleCompleted: function(position) {
var todo = this.todos[position];
todo.completed = !todo.completed;
},
//Method for toggling ALL todo items:
toggleAll: function() {
var totalTodos = this.todos.length;
//Counting the ones that are completed
var completedTodos = 0;
//Getting the number of the completed todos:
for (var i = 0; i < totalTodos; i++) {
if (this.todos[i].completed === true) {
//For every todo item that is completed, increase completedTodos by 1;
completedTodos++;
}
}
//Case 1: If everything is true, the turn it into FALSE;
if (completedTodos === totalTodos) {
for (var i = 0; i < totalTodos; i++) {
this.todos[i].completed = false
}
//Case 2: Otherwise, make everything TRUE;
} else {
for (var i = 0; i < totalTodos; i++) {
this.todos[i].completed = true;
};
};
}
}
//Object for the BUTTON HANDLERS:
var handlers = {
addTodo: function() {
var addTodoText = document.getElementById("addTodoTextInput");
todoList.addTodo(addTodoTextInput.value);
//Clear the input
addTodoText.value = "";
view.displayTodos();
},
//Change todo
changeTodo: function() {
var changeTodoText = document.getElementById("changeTodoText");
var changeTodoPosition = document.getElementById("changeTodoPosition");
//Get the CHANGE TODO method in the object TODOLIST and set these parameters
todoList.changeTodo(changeTodoPosition.valueAsNumber, changeTodoText.value);
//Clear the inputs
changeTodoText.value = "";
changeTodoPosition.value = "";
//Call upon VIEW object and trigger displayTodos() method/function;
view.displayTodos();
},
deleteTodo: function(position) {
todoList.deleteTodo(position);
view.displayTodos();
},
deleteAll: function(position) {
todoList.todos.splice(position);
view.displayTodos();
},
toggleCompleted: function(position) {
var toggleCompletedInput = document.querySelector("#" + position + " toggleBtn");
todoList.toggleCompleted(toggleCompletedInput.valueAsNumber);
toggleCompletedInput.value = "";
view.displayTodos();
},
toggleAll: function() {
todoList.toggleAll();
view.displayTodos();
}
};
//Object that is used only to DISPLAY the items:
var view = {
displayTodos: function() {
var todosUl = document.querySelector("ul");
todosUl.innerHTML = '';
for (var i = 0; i < todoList.todos.length; i++) {
var todoLi = document.createElement("li");
var todo = todoList.todos[i];
todoLi.id = i;
todoLi.textContent = todo.todoText;
if (todo.completed === true) {
todoLi.classList.toggle("checked");
} else {
todoLi.classList.toggle("notCompleted");
todoLi.appendChild(this.createToggleButton());
}
todoLi.appendChild(this.createDeleteButton());
todosUl.appendChild(todoLi);
}
},
createDeleteButton: function() {
var deleteButton = document.createElement("button");
deleteButton.textContent = "DELETE";
deleteButton.className = "deleteBtn";
return deleteButton;
},
createToggleButton: function() {
var toggleButton = document.createElement("button");
toggleButton.textContent = "Completed";
toggleButton.className = "toggleBtn";
return toggleButton;
},
//
setUpEventListeners: function() {
var todosUl = document.querySelector("ul");
todosUl.addEventListener("click", function(event) {
var elementClicked = event.target;
if (elementClicked.className === "deleteBtn") {
handlers.deleteTodo(parseInt(elementClicked.parentNode.id));
}
if (elementClicked.className === "toggleBtn") {
todoList.toggleCompleted(parseInt(elementClicked.parentNode.id));
view.displayTodos();
}
});
}
}
view.setUpEventListeners();
&#13;
* {
margin: 0;
padding: 0;
}
body {
background-color: #dcdde1;
font-family: 'Poppins', sans-serif;
}
li {
color: #eee;
margin: 5px 0;
list-style-type: none;
padding: 10px;
background-color: grey;
display: flex;
justify-content: flex-start;
align-items: center;
user-select: none;
width: 100%;
animation: listitem 1s 1 forwards;
position: relative;
border-radius: 5px;
}
li.deleted {
animation: listItem 1s 1;
}
@keyframes listItem {
from {
opacity: 0
}
to {
opacity: 1
}
;
}
li.checked {
background-color: #4cd137;
color: #eee;
}
li.checked:before {
color: #eee;
margin: 0 10px;
content: "\2714";
animation: checkmark 1s 1 forwards;
}
@keyframes checkmark {
0% {
transform: scale(0);
}
60% {
transform: scale(1.3);
}
100% {
transform: scale(1);
}
}
li.notCompleted {
background-color: #e84118;
color: #eee;
}
li.notCompleted:before {
content: "\2716";
animation: check 1s 1 forwards;
margin: 0 10px;
}
@keyframes check {
0% {
transform: scale(0);
}
60% {
transform: scale(1.3);
}
100% {
transform: scale(1);
}
}
ul li .deleteBtn {
background-color: #eee;
color: #e84118;
cursor: pointer;
position: absolute;
right: 10px;
bottom: 3px;
animation: delete 0.5s ease-out 1 forwards;
}
.deleteBtn:hover {
background-color: #353b48;
color: #eee;
}
.toggleBtn {
background-color: #eee;
color: #e84118;
cursor: pointer;
position: absolute;
right: 70px;
bottom: 3px;
animation: delete 0.5s ease-out 1 forwards;
}
.toggleBtn:hover {
background-color: #4cd137;
color: #eee;
}
.toggleBtn.removed {
display: none;
}
@keyframes delete {
0% {
transform: scale(0);
}
50% {
transform: scale(1.05);
}
80% {
transform: scale(0.95);
}
100% {
transform: scale(1);
}
}
.wrapper {
max-width: 1200px;
margin: 0 auto;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
padding: 10px;
}
h1 {
color: #e84118;
font-size: 35px;
font-weight: 700;
text-transform: uppercase;
}
h1 span {
color: #0097e6;
font-size: 65px;
font-weight: 800;
opacity: 0;
letter-spacing: -50px;
animation: headerSpan 2s 0.5s 1 forwards;
}
@keyframes headerSpan {
0% {
opacity: 0;
letter-spacing: -50px;
transform: scale(0);
}
50% {
letter-spacing: 10px;
}
100% {
opacity: 1;
transform: scale(1);
letter-spacing: 0px;
}
}
input {
padding: 5px;
border: none;
background-color: #f5f6fa;
box-shadow: 0 1px 5px rgba(0, 0, 0, 0.2);
border-radius: 3px;
color: #e84118;
font-family: 'Poppins';
width: 100%;
margin: 2px 0;
}
input:focus {
outline: none !important;
}
input::placeholder {
color: #e84118;
font-family: "Poppins";
font-style: italic;
font-size: 12px;
padding-left: 5px;
}
button {
margin: 5px 0;
padding: 3px;
border: none;
border-radius: 3px;
font-family: 'Poppins';
text-transform: uppercase;
color: #eee;
background-color: #00a8ff;
font-weight: bold;
font-size: 14px;
transition: 0.2s ease-out;
}
button:focus {
outline: none!important;
}
button:hover {
background-color: #e84118;
color: #eee;
}
.container_todo {
border-radius: 5px;
padding: 35px;
display: flex;
flex-direction: column;
background-color: #f4f4f4;
box-shadow: 0 2px 25px rgba(0, 0, 0, 0.25);
animation: container 1s 1 forwards;
}
.toggleAllButtons {
display: flex;
flex-direction: column;
justify-content: space-between;
}
.all.active {
background-color: red;
}
&#13;
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>The Todo List</title>
<link rel="stylesheet" type="text/css" href="styles.css">
<link href="https://fonts.googleapis.com/css?family=Gaegu|Indie+Flower|Pacifico|Raleway" rel="stylesheet">
</head>
<body>
<div class="wrapper">
<!-- Title -->
<h1>The <span>Todo</span> List !</h1>
<!-- TODO LIST container -->
<div class="container_todo">
<!-- BUTTONS -->
<!-- Add Todo item -->
<div class="add">
<button onclick="handlers.addTodo()">Add todo</button>
<input type="text" id="addTodoTextInput" placeholder="Add a Todo item">
</div>
<!-- Change Todo Item-->
<div class="change">
<button onclick="handlers.changeTodo()">Change Todo</button>
<input type="text" id="changeTodoText" placeholder="Change a Todo item">
<input type="number" id="changeTodoPosition" placeholder="Choose which Item to change">
</div>
<!-- Toggle completed Todo item -->
<div class="toggleAllButtons">
<!-- Toggle All items button -->
<div class="all">
<button onclick="handlers.toggleAll()">Toggle All</button>
<button onclick="handlers.deleteAll()">Delete All</button>
</div>
</div>
<ul></ul>
</div>
</div>
<!-- /////////////////////////////////////// -->
<!-- JS link -->
<script src="script.js"></script>
</body>
</html>
&#13;