javascript - 事件委托(delegate)后表单不起作用

标签 javascript jquery html dom

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

未捕获的类型错误:字符串不是函数

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

// 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 的全局引用作为循环变量,它以字符串形式覆盖全局任务(函数)。然后,当您说 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 作为构造函数,我建议您以大写字母开头这些名称,例如 Task ToDoList

关于javascript - 事件委托(delegate)后表单不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28314242/

相关文章:

javascript - 引发 Backbone.js View 事件

javascript - Laravel 将旧数据存储在文本字段中

javascript - Google Map Bug,Dragend Event 也会触发 IE 中的 Click Event

javascript - 如何添加一个简单的卡片翻转动画?

html - CSS @media 停止在 textarea 焦点上的移动设备上工作

html - 如何使用 CSS 将两个 block 居中,中间有一些间隙?

javascript - 获取没有 id 的元素的值

javascript - 正则表达式返回空字符空间并且未定义?

jquery - 无法将图像设置为 jsPlumb 端点

html - HTML 选择框的高度(下拉)