以下是我在rails视图中的代码:
<div class="lists">
<h1>Your Todo Lists</h1>
<div class="incomplete-list">
<p>This is the incomplete list</p>
<% @incomplete_list.items.each do |item| %>
<div class="incomplete-item">
<%= form_for :item, url: item_path(item), method: :post, html: { class: "item-box" } do |f|%>
<%= f.label item.title %>
<%= f.check_box item.id %>
<% end %>
</div>
<% end %>
</div>
<div class="complete-list">
<p>This is the completed list</p>
<% @complete_list.items.each do |item| %>
<div class="complete-item">
<%= form_for :item, url: item_path(item), method: :post, html: { class: "item-box" } do |f|%>
<%= f.label item.title %>
<%= f.check_box item.id %>
<% end %>
</div>
<% end %>
</div>
</div>
<script>
$(document).ready(function() {
var changeDom = function(itemRow) {
var parentList = itemRow.parent()
itemRow.remove()
// I am so dumb, you can't remove an itemRow first and then ask for its parent. You dumb dumb. It's [] if you
// ask for the parent after you remove it. So you need to set it first with var parent =
if (parentList.attr("class") === "incomplete-list") {
$(".complete-list").append(itemRow)
}
else {
$(".incomplete-list").append(itemRow)
}
}
var itemLists = $(".lists")
itemLists.find(":checkbox").on("change", function(box){
var box = $(this)
var item_number = parseInt(box[0].name.match(/[^[\]]+(?=])/g)[0])
$.ajax( { type: "PUT",
url: "items/" + item_number,
data: { id: item_number },
success: function(text) {
changeDom($(box[0].closest("div")))
}
});
})
})
</script>
它第一次运作。我使用不完整的项目和完整项目呈现此页面。但是在我点击它们并且从一个列表跳到另一个列表之后......他们失去了听众而不再工作。一个人做什么?
另外,如果选中一个不完整的框,我会在另一个列表中检查它,并且当一个复选框位于完整列表中时,它将在另一个框中取消选中。
答案 0 :(得分:2)
如果你删除了一个dom元素,那么它也会删除它的听众。
你可以做两件事:
您的changeDom
功能可以修改,因此它不会删除该元素,而是应该将元素从一个列表移动到另一个列表。如果移动元素,则仍将绑定侦听器。
查看jQuery中的detach
方法,作为移动元素的一种方法,但保持它的侦听器绑定
但更好的方法是更实际地将事件绑定到列表中的每个复选框/行。
相反,使用事件委派来绑定更高级别的单击事件。哪个更有效,因为您不必为每个复选框创建侦听器。相反,整个列表只有一个监听器 - 但它仍然会响应每个复选框的点击次数。
$(".lists").on("change", ":checkboxes", function() {
// do stuff
});
因为您正在倾听更高级别的事件,所以如果您移动复选框元素也不重要 - 没有事件侦听器会被中断。
以下是有关事件委派的一些文档:
答案 1 :(得分:0)
问题是使用.remove()将删除附加的事件处理程序和数据
除了元素本身,所有绑定事件和jQuery 与元素关联的数据将被删除
在你的情况下,因为在删除后元素被添加到一个或另一个元素,所以不需要调用com.plivo.example.outbound.Call
你只需将它附加到目标元素
remove()
如果您仍想遵循相同的流程,请使用detach()
var changeDom = function (itemRow) {
var parentList = itemRow.parent()
if (parentList.attr("class") === "incomplete-list") {
$(".complete-list").append(itemRow)
} else {
$(".incomplete-list").append(itemRow)
}
}