未捕获的引用错误:elementChecked未定义。

3

我刚接触 JavaScript,在构建待办事项列表时遇到了一个问题。我尝试添加一个复选框,并将 #id 推入 handlers.toggleCompleted,以便标记该项已完成。

我能够正确运行 if 语句。

if (elementChecked.childNodes[3].checked) {
          console.log(elementClicked.parentNode.id);

然而,我在这里遇到了未捕获的引用错误。
if (elementChecked.childNodes[3].checked) {
          handlers.toggleCompleted(elementChecked.parentNode.id);

以下是完整的代码,如果这不是一个好问题,请原谅我还在学习这门语言。

let todoList = {
    todos: [],
    addTodo: function(todoText) {
      this.todos.push({
        todoText: todoText,
        completed: false
      });
    },
    changeTodo: function(position, todoText) {
      this.todos[position].todoText = todoText;
    },
    deleteTodo: function(position) {
      this.todos.splice(position, 1);
    },
    toggleCompleted: function(position) {
      let todo = this.todos[position];
      todo.completed = elementChecked.childNodes[3].checked;
    },
    toggleAll: function() {
      let totalTodos = this.todos.length;
      let completedTodos = 0;

      // Get number of completed todos.
      this.todos.forEach(function(todo) {
        if (todo.completed === true) {
          completedTodos++;
        }
      });

      this.todos.forEach(function(todo) {
        //case 1: if everything is true make everything flase
        if (completedTodos === totalTodos) {
          todo.completed = false;
        } else {
          //case 2: if everything is false make everything true
          todo.completed = true;
        }
      });
    }
  };

  let handlers = {
    addTodo: function() {
      let addTodoTextInput = document.getElementById('addTodoTextInput');
      todoList.addTodo(addTodoTextInput.value);
      addTodoTextInput.value = '';
      view.displayTodos();
    },
    changeTodo: function(position, todoText){
        todoList.changeTodo(position, todoText);
      view.displayTodos();
    },
    deleteTodo: function(position) {
      todoList.deleteTodo(position);
      view.displayTodos();
    },
    toggleCompleted: function(position) {
      todoList.toggleCompleted(position);
      view.displayTodos();
    },
    toggleAll: function() {
      todoList.toggleAll();
      view.displayTodos();
    }
  };

  let view = {
    displayTodos: function() {
      let todosUl = document.querySelector('ul');
      todosUl.innerHTML = '';
      todoList.todos.forEach(function(todo, position) {
        let todoLi = document.createElement('li');
        let todoTextWithCompletion = '';

        if (todo.completed === true) {
          todoTextWithCompletion = '(x) ' + todo.todoText;
        } else {
          todoTextWithCompletion = '( ) ' + todo.todoText;
        }

        todoLi.id = position;
        todoLi.textContent = todoTextWithCompletion;
        todoLi.appendChild(this.createDeleteButton());
        todoLi.appendChild(this.createChangeButton());
        todoLi.appendChild(this.createCompleteButton());



        todosUl.appendChild(todoLi);
      }, this);
    },
    createDeleteButton: function() {
      let deleteButton = document.createElement('button');
      deleteButton.textContent = 'Delete';
      deleteButton.className = 'deleteButton';
      return deleteButton;
    },
    createChangeButton: function() {
      let changeButton = document.createElement('button');
      changeButton.textContent = 'Change';
      changeButton.className = 'changeButton';
      return changeButton;
    },
    createCompleteButton: function() {
      let completeButton = document.createElement('input');
      completeButton.setAttribute("type", "checkbox");
      completeButton.className = 'todoComplete';
      return completeButton;
    },
    setUpEventListeners: function() {
      let todosUl = document.querySelector('ul');
      todosUl.addEventListener('click', function(event) {
        let elementClicked = event.target;
        let elementChecked = document.getElementById(parseInt(elementClicked.parentNode.id));
        if (elementClicked.className === 'deleteButton') {
          handlers.deleteTodo(parseInt(elementClicked.parentNode.id));
        }
        if (elementClicked.className === 'changeButton') {
          let selectedTodoText = parseInt(elementClicked.parentNode.id);
          let changedTextValue = prompt("Please enter new text:", selectedTodoText);
          handlers.changeTodo(selectedTodoText, changedTextValue);
        }
        if (elementChecked.childNodes[3].checked) {
          handlers.toggleCompleted(elementClicked.parentNode.id);
          console.log(elementClicked.parentNode.id);
        } else {
          elementChecked.style.background = 'transparent';
        }
      });
    }
  };
  view.setUpEventListeners();

1
也许问题出在 parseInt(elementClicked.parentNode.id) 上。为什么要将 id 解析为 int?它真的是一个 int 吗?还是一个包含字符和数字的字符串? - reisdev
我正在使用parseInt将ID从字符串转换为值,以便它可以作为数字在todo数组中引用。我尝试删除parseInt但问题似乎是在if语句中运行elementClicked导致了未捕获的ReferenceError错误。 - luke hinrichs
1个回答

0

我明白了(有点),这是因为它没有在todoList.toggleCompleted范围内被定义。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接