单击li元素时出现“奇怪”行为

时间:2014-12-03 04:55:42

标签: javascript jquery javascript-events

我试图为动态生成的<li>元素添加一个类,但它有一个非常奇怪的行为。使用单个<li>它可以很好地工作,但在添加另一个元素后,class属性将被添加而没有值。添加第三个<li>后,它将再次起作用(基本上仅当<li>元素的数量为奇数时才有效。)

&#13;
&#13;
var JSTasker = {
  updateTaskCounter: function() {
    var taskCount = $('div#tasks ul').children().not('li.completed').size();
    $('span#task_counter').text(taskCount);
  },
  sortTasks: function() {
    var taskList = $('div#tasks ul');
    var allCompleted = $(taskList).children('.completed');
    allCompleted.detach();
    allCompleted.appendTo(taskList);
  },
  updatePage: function() {
    this.updateTaskCounter();
    this.sortTasks();
  }
};

$(document).ready(function() {
  $('input#task_text').focus();
  $('form#add_task').on('submit', function(event) {
    event.preventDefault();
    var taskText = $('input#task_text').val();
    var taskItem = "<li>" + taskText + "</li>";
    $('div#tasks ul').append(taskItem);
    $('input#task_text').val(null);
    JSTasker.updatePage();
    $('div#tasks ul').on('click', 'li', function(event) {
      event.preventDefault();
      $(this).toggleClass('completed');
      JSTasker.updatePage();
    });
  });
});
&#13;
h1,
h2,
ul,
li {
  margin: 0px;
  padding: 0px;
}
html {
  background: #333;
  font-family: 'Gill Sans Light', 'Helvetica', 'Arial';
  font-size: 90%;
}
body {
  width: 400px;
  margin: 10px auto;
  border: 1px solid #EEE;
  background: #F6F6F6;
  padding: 10px 20px;
}
fieldset {
  border: 2px solid #CCC;
  padding: 10px;
  margin: 10px 0px 0px 0px;
}
input[type=text] {
  width: 300px;
  padding-right: 20px;
}
input[type=submit] {} #tasks {
  margin: 20px 0px 0px 0px;
}
h2 {
  margin-bottom: 10px;
}
h2 span#task_counter {
  font-size: 80%;
  color: #999;
}
#tasks ul {
  list-style-type: none;
}
#tasks ul li {
  padding: 6px 10px 3px 20px;
  height: 1.6em;
}
#tasks ul li:hover {
  background: #FFF8DC;
  text-decoration: underline;
}
#tasks ul li.completed {
  background: url('icons/accept.png') no-repeat 0px 5px;
  text-decoration: line-through;
  color: #999;
}
.trash {
  float: right;
  padding: 2px;
}
.trash:hover {
  background: #F99;
  cursor: pointer;
}
&#13;
<!doctype html>
<html>

<head>
  <meta charset="UTF-8" />
  <title>Tasker</title>
  <link rel='stylesheet' type="text/css" href='JSTasker.css' />
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
  <script src="JSTasker.js"></script>
</head>

<body>
  <h1>JSTasker</h1>
  <form id='add_task'>
    <fieldset>
      <legend>Add a Task</legend>
      <input type='text' name='task_text' id='task_text' />
      <input type='submit' name='add_button' value='Add' />
    </fieldset>
  </form>

  <div id='tasks'>
    <h2>Your Tasks <span id='task_counter'></span></h2>
    <ul>
    </ul>
  </div>
</body>

</html>
&#13;
&#13;
&#13;

这是有问题的部分:

    $('div#tasks ul').on('click', 'li', function(event) {
        event.preventDefault();
        $(this).toggleClass('completed');
        JSTasker.updatePage();
    });

该应用程序基于this教程。

3 个答案:

答案 0 :(得分:3)

在表单提交之外添加onclick处理程序,现在每次提交表单时都会初始化您的onclick事件。但$().on()用于动态绑定,您只需要调用一次

$(document).ready(function() {

    $('input#task_text').focus();

  $('form#add_task').on('submit', function(event) {
    event.preventDefault();

    var taskText = $('input#task_text').val();
    var taskItem = "<li>" + taskText + "</li>";
    $('div#tasks ul').append(taskItem);
    $('input#task_text').val("");

    JSTasker.updatePage();

  });
    $('div#tasks ul').on('click', "li", function(event) {
      event.preventDefault();
      $(this).toggleClass('completed');
      JSTasker.updatePage();

    });

});

答案 1 :(得分:2)

每次点击添加按钮,您都会将点击事件绑定到li。拿出这个代码就可以了。它适用于奇数个元素,因为它将绑定事件奇数次。假设您添加了3个li,因此它会调用点击事件3次。第一次添加类,然后删除,然后再次添加类。但是对于偶数li s它将会失败,因为它将首先添加类然后将其删除。

&#13;
&#13;
var JSTasker = {
  updateTaskCounter: function() {
    var taskCount = $('div#tasks ul').children().not('li.completed').size();
    $('span#task_counter').text(taskCount);
  },
  sortTasks: function() {
    var taskList = $('div#tasks ul');
    var allCompleted = $(taskList).children('.completed');
    allCompleted.detach();
    allCompleted.appendTo(taskList);
  },
  updatePage: function() {
    this.updateTaskCounter();
    this.sortTasks();
  }
};

$(document).ready(function() {
  $('input#task_text').focus();
  $('form#add_task').on('submit', function(event) {
    event.preventDefault();
    var taskText = $('input#task_text').val();
    var taskItem = "<li>" + taskText + "</li>";
    $('div#tasks ul').append(taskItem);
    $('input#task_text').val(null);
    JSTasker.updatePage();
  });
  
  $('div#tasks ul').on('click', 'li', function(event) {
      event.preventDefault();
      $(this).toggleClass('completed');
      JSTasker.updatePage();
    });
});
&#13;
h1,
h2,
ul,
li {
  margin: 0px;
  padding: 0px;
}
html {
  background: #333;
  font-family: 'Gill Sans Light', 'Helvetica', 'Arial';
  font-size: 90%;
}
body {
  width: 400px;
  margin: 10px auto;
  border: 1px solid #EEE;
  background: #F6F6F6;
  padding: 10px 20px;
}
fieldset {
  border: 2px solid #CCC;
  padding: 10px;
  margin: 10px 0px 0px 0px;
}
input[type=text] {
  width: 300px;
  padding-right: 20px;
}
input[type=submit] {} #tasks {
  margin: 20px 0px 0px 0px;
}
h2 {
  margin-bottom: 10px;
}
h2 span#task_counter {
  font-size: 80%;
  color: #999;
}
#tasks ul {
  list-style-type: none;
}
#tasks ul li {
  padding: 6px 10px 3px 20px;
  height: 1.6em;
}
#tasks ul li:hover {
  background: #FFF8DC;
  text-decoration: underline;
}
#tasks ul li.completed {
  background: url('icons/accept.png') no-repeat 0px 5px;
  text-decoration: line-through;
  color: #999;
}
.trash {
  float: right;
  padding: 2px;
}
.trash:hover {
  background: #F99;
  cursor: pointer;
}
&#13;
<!doctype html>
<html>

<head>
  <meta charset="UTF-8" />
  <title>Tasker</title>
  <link rel='stylesheet' type="text/css" href='JSTasker.css' />
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
  <script src="JSTasker.js"></script>
</head>

<body>
  <h1>JSTasker</h1>
  <form id='add_task'>
    <fieldset>
      <legend>Add a Task</legend>
      <input type='text' name='task_text' id='task_text' />
      <input type='submit' name='add_button' value='Add' />
    </fieldset>
  </form>

  <div id='tasks'>
    <h2>Your Tasks <span id='task_counter'></span></h2>
    <ul>
    </ul>
  </div>
</body>

</html>
&#13;
&#13;
&#13;

答案 2 :(得分:1)

您的代码仅使用奇数个任务,因为每次提交表单时都会向每个<li>添加一个新的点击处理程序。这意味着当你有两个<li>时,你会拨打toggleClass两次,然后无处可去。您可以在alert("hi")来电后将toggleClass添加到当前代码中进行确认。