Javascript $.remove()正在从分离的元素中删除事件?

Javascript $.remove()正在从分离的元素中删除事件?,javascript,dom,jquery,Javascript,Dom,Jquery,当鼠标悬停在列表项上时,该元素被附加到列表项上,当鼠标悬停时,该元素被分离 单击元素时,它将被分离,然后它所属的列表项将从DOM中删除 我的HTML: <div id="cart"> <ul> <li> <a data-item="a">item A</a></li> <li> <a data-item="b">item B</a></li&g

当鼠标悬停在列表项上时,该元素被附加到列表项上,当鼠标悬停时,该元素被分离

单击元素时,它将被分离,然后它所属的列表项将从DOM中删除

我的HTML:

<div id="cart">
    <ul>
        <li> <a data-item="a">item A</a></li>
        <li> <a data-item="b">item B</a></li>
        <li> <a data-item="c">item C</a></li>
        <li> <a data-item="d">item D</a></li>            
        <li> <a data-item="e">item E</a></li>
        <li> <a data-item="f">item F</a></li>
        <li> <a data-item="g">item G</a></li>
        <li> <a data-item="h">item H</a></li>         
    </ul>    

</div>

  • 这类似于我的代码

    问题是,此元素的单击侦听器也会随列表项一起被删除,即使该元素在
    $激发之前已被分离。remove()
    激发,因此它不应受到影响


    我在这里做错了什么?

    你认为发生的事情是正确的,只是当你拆下
    delKnob
    时,你的鼠标会立即进入包含它的
    li
    ,这意味着它会被重新连接,所以当
    li
    被移除时,
    delKnob
    仍然是一个孩子,因此也会被删除

    我通过在代码中添加
    console.log()
    来测试这一点:

    this.cart.on('mouseenter', 'li', function () {
        console.log("delKnob attached!");
        delKnob.appendTo(this);
    })
    
    通过移除
    setTimeout
    中的
    delKnob
    来解决此问题:

    setTimeout(function () {
        li.find('.delKnob').detach();
        li.remove();
    }, 500);
    
    这假设将类
    delKnob
    添加到元素中

    演示:

    作为旁注,我将简化整个过程,只需在每个
    li
    中添加一个
    delKnob
    。然后,您只需显示/隐藏它们,而不必担心删除处理程序。它还大大简化了代码:

    function plugin(node, opts) {
          this.cart = $(node);
    
          this.cart.find('li').append($('<i class="delKnob"/>').text('×').hide());
    
          this.cart.on('click', '.delKnob', function () {
              var li =  $(this).closest('li').addClass('removing');
              setTimeout(function () {
                 li.remove();
              }, 500);
          });
    
          this.cart.on('mouseenter', 'li', function () {
              $(this).find('.delKnob').show();
          })
              .on('mouseleave', 'li', function () {
              $(this).find('.delKnob').hide();
          });   
    };
    
    函数插件(节点,选项){
    this.cart=$(节点);
    this.cart.find('li').append($('').text('×').hide();
    此.cart.on('click','.delknow',函数(){
    var li=$(this).closest('li').addClass('removing');
    setTimeout(函数(){
    li.remove();
    }, 500);
    });
    this.cart.on('mouseenter','li',function(){
    $(this.find('.delknow').show();
    })
    .on('mouseleave','li',函数(){
    $(this.find('.delknow').hide();
    });   
    };
    

    演示:

    您可以使用事件委派并将事件绑定到容器(
    this.cart
    ),该容器处理任何被单击的
    .delKnob
    子体,而不是将事件绑定到(重新)移动的
    delKnob

    delKnob = $('<i class="delKnob" />').text('×');      
    
    this.cart
      .on('click', '.delKnob', function(){              
        var item = $(this).parent().find('[data-item]').data('item');
        $(this).detach();
        self.remove(item);
      });
    
    delKnob=$('').text('×');
    这是购物车
    .on('click','.delKnob',function(){
    var item=$(this.parent().find('[data item]')。data('item');
    $(this.detach();
    自行移除(项目);
    });
    

    @bfavaretto如果他们被委派,这意味着他们属于集装箱……这是
    #cart
    ,而不是
    li
    s@Ian我在发帖后才意识到,但删除该评论的速度不够快…@bfavaretto,我意识到在我的评论提交后:)看起来你是对的,在移除li(从setTimeout回调中)之前,可以通过拆下delKnob来修复它。看有趣的。如果它得到
    .remove()
    d,如何将其重新附加到DOM中?我认为只有使用
    .detach()
    才能做到这一点。也许我需要读那些东西again@Ian,我不确定,但它可能与从
    插件中初始化的
    delKnob
    变量中附加一些内容有关。它是一个jQuery对象,但是处理程序在DOM中,所以它的行为有点奇怪。是的,就是这样。我添加了一个临时变量来检查状态:@OneTrickPony:我认为只需在每个
    li
    上添加一个删除按钮,就可以大大简化代码。这意味着要担心的事情少了很多。我也会对整个购物车使用一个委托处理程序,而不是像我上面的新示例那样在每个
    delKnob
    中添加一个。谢谢!这似乎也解决了这个问题
    delKnob = $('<i class="delKnob" />').text('×');      
    
    this.cart
      .on('click', '.delKnob', function(){              
        var item = $(this).parent().find('[data-item]').data('item');
        $(this).detach();
        self.remove(item);
      });