表格在事件授权后不起作用

时间:2015-02-04 05:40:34

标签: javascript jquery html dom

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

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

1 个答案:

答案 0 :(得分:2)

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

因此,将task变量设为本地变量

for (var task in this.list) {}

演示

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

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

但是作为一个建议,由于您同时使用tasktoDoList作为构造函数,我建议您使用大写字母开始这些名称,例如Task和{{1} }。