如何在JS中删除动态创建的按钮?

时间:2018-04-16 20:54:08

标签: javascript button

我已经在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();

1 个答案:

答案 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;
}

&#13;
&#13;
//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;
&#13;
&#13;