Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 选中后的复选框将丢失jquery中的侦听器_Javascript_Ruby On Rails - Fatal编程技术网

Javascript 选中后的复选框将丢失jquery中的侦听器

Javascript 选中后的复选框将丢失jquery中的侦听器,javascript,ruby-on-rails,Javascript,Ruby On Rails,以下是我在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="incom

以下是我在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>

你的待办事项清单
这是不完整的列表

这是完整的列表

$(文档).ready(函数(){ var changeDom=函数(itemRow){ var parentList=itemrrow.parent() itemRow.remove() //我太笨了,你不能先删除itemRow,然后再请求它的父项。你这个笨蛋。如果你 //删除父对象后请求它。因此需要先使用var parent设置它= if(parentList.attr(“类”)=“不完整列表”){ $(“.complete list”).append(itemRow) } 否则{ $(“.complete list”).append(itemRow) } } var itemLists=$(“.lists”) ItemList.find(“:checkbox”)。打开(“更改”,函数(框){ 变量框=$(此) var item_number=parseInt(框[0].name.match(/[^[\]]+(?=])/g)[0]) $.ajax({type:“PUT”, url:“项目/”+项目编号, 数据:{id:item_number}, 成功:函数(文本){ 变更域($(框[0]。最近的(“div”)) } }); }) })
它第一次起作用。我用不完整项和完整项呈现此页面。但当我点击它们,它们从一个列表跳到另一个列表后……它们失去了听众,不再工作。一个人做什么

还有,如果选中了不完整的框,它将在另一个列表中被选中,如果选中的框在完整列表中,它将在另一个列表中被取消选中。问题在于使用它将删除附加的事件处理程序和数据

除了元素本身,所有绑定事件和jQuery 与元素关联的数据将被删除

在您的情况下,由于元素是在删除之后添加到一个或另一个元素中的,因此无需调用
remove()
,您只需将其附加到目标元素即可

var changeDom = function (itemRow) {
    var parentList = itemRow.parent()
    if (parentList.attr("class") === "incomplete-list") {
        $(".complete-list").append(itemRow)
    } else {
        $(".incomplete-list").append(itemRow)
    }
}
如果仍要遵循相同的流程,请使用


如果删除dom元素,那么是的,它的侦听器也将被删除

你可以做两件事:

  • 可以修改
    changeDom
    函数,使其不删除元素,而是将元素从一个列表移动到另一个列表。如果移动元素,则侦听器仍将被绑定

    查看jQuery中的
    detach
    方法,作为移动元素的一种方式,但要保持其侦听器的绑定

  • 但是一种更好、更有效的方法是不将事件实际绑定到列表中的每个复选框/行

    相反,使用事件委派在更高级别绑定单击事件。哪个更有效,因为您不必为每个复选框创建侦听器。相反,整个列表只有一个侦听器,但它仍然会对每个复选框的单击作出响应

    $(".lists").on("change", ":checkboxes", function() {
       // do stuff
    });
    
    因为您正在侦听更高级别的事件,所以移动复选框元素并不重要,不会中断任何事件侦听器

    以下是一些关于活动委派的文档:

  • $(".lists").on("change", ":checkboxes", function() {
       // do stuff
    });