事件委托后表格不起作用

Form not working after event delegation

我有一个表单可以动态地将文本附加到 HTML 中的无序列表,并带有一个用于标记为 'completed' 的复选框。我可以添加多个任务,将它们标记为完成,但在标记任何复选框后无法继续。控制台记录以下错误:

Uncaught TypeError: string is not a function

我不确定该错误是什么意思,因为我只能在选中复选框之前继续添加列表项。

// all jquery dom actions can only be called inside document ready.

function toDoList() {
    this.list = [];
}

function task(description) {
    this.description = description;
    this.completed = false;
}

toDoList.prototype.add = function (todo) {
    this.list.push(todo)
}

toDoList.prototype.complete = function (todo) {
    for (task in this.list) {
        if (this.list[task].description === todo) {
            this.list[task].completed = true
            console.log("Woot! You've completed: " + todo)
        } else {
            console.log("Couldn't find that task!")
        }
    }

}

var myList = new toDoList();
$(document).ready(function () {

    $("#todoform").on("submit", function (e) {
        e.preventDefault();
        var taskDescription = $("#todo").val()
        var myTask = new task(taskDescription)
        myList.add(myTask)
        $("#printout ul").append("<li class=\"task\"><input type=\"checkbox\">" + myTask.description + "</li>")
        $('#todo').val('');
        console.log(myList)
    });

    $('ul').delegate('.task', 'change', function () {
        if (!this.checked) {
            $(this).toggleClass("completed")
            var task = $(this).text()
            myList.complete(task)
            console.log(myList)
        }
    });

});

你可以查看我的 JSFiddle here:

这是因为 complete 处理程序中的 for 循环,您使用了对 task 的全局引用作为循环变量,它覆盖了全局 task(函数)作为字符串。然后当你说 new task() 时,task 是一个字符串而不是导致错误 Uncaught TypeError: string is not a function

的函数

所以将 task 变量设置为本地变量

for (var task in this.list) {}

演示

// all jquery dom actions can only be called inside document ready.

function ToDoList() {
  this.list = [];
}

function Task(description) {
  this.description = description;
  this.completed = false;
}

ToDoList.prototype.add = function(todo) {
  this.list.push(todo)
}

ToDoList.prototype.complete = function(todo) {
  for (var task in this.list) {
    if (this.list[task].description === todo) {
      this.list[task].completed = true
      console.log("Woot! You've completed: " + todo)
    } else {
      console.log("Couldn't find that task!")
    }
  }

}

var myList = new ToDoList();
$(document).ready(function() {

  $("#todoform").on("submit", function(e) {
    e.preventDefault();
    var taskDescription = $("#todo").val()
    var myTask = new Task(taskDescription)
    myList.add(myTask)
    $("#printout ul").append("<li class=\"task\"><input type=\"checkbox\">" + myTask.description + "</li>")
    $('#todo').val('');
    console.log(myList)
  });

  $('ul').delegate('.task', 'change', function() {
    if (!this.checked) {
      $(this).toggleClass("completed")
      var task = $(this).text()
      myList.complete(task)
      console.log(myList)
    }
  });

});
body {
  background-color: #D1D1D1
}
#todoform {
  margin: 5em auto 0 auto;
  width: 20%;
}
#printout {
  width: 800px;
  min-height: 1000px;
  background-color: white;
  margin: 1em auto 0 auto;
  color: black;
  text-indent: 1em;
}
#printout p {
  font-size: 2em;
}
#printout p:nth-child(even) {
  background-color: #D1D1D1;
}
.completed {
  text-decoration: line-through;
}
#task {
  line-style-type: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
  <form id="todoform" action="#" method="post">
    <input type="text" id="todo" name="todo" placeholder="Enter Your Todo" />
    <input type="submit" value="Add" id="addTodo" />
  </form>
  <div id="printout">
    <ul></ul>
  </div>
</div>

但作为一个建议,由于您同时使用 tasktoDoList 作为构造函数,我建议您以大写字母开头这些名称,例如 TaskToDoList.