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

nic*_*ass 3 javascript jquery dom

当鼠标悬停在列表项目上时,该元素将附加到列表项目,并在鼠标移出时分离.

单击该元素时,它将被分离,然后从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>
Run Code Online (Sandbox Code Playgroud)

我的JavaScript:

  function plugin(node, opts){
    var self = this;
        delKnob = $('<i />').text('×');

    this.cart = $(node);

    delKnob
      .on('click', function(){              
        var item = $(this).parent().find('[data-item]').data('item');
        $(this).detach();
        self.remove(item);
      });

    this.cart
      .on('mouseenter', 'li', function(){
        delKnob.appendTo(this);
      })
      .on('mouseleave', 'li', function(){
        delKnob.detach();
      });
  }

  plugin.prototype = {
    remove: function(item){
      var li = this.cart.find('[data-item="' + item + '"]').closest('li');
      li.addClass('removing');
      setTimeout(function(){
        li.remove();   
      }, 500);    
    }
  };

new plugin('#cart');
Run Code Online (Sandbox Code Playgroud)

我已经设置了一个类似于我的代码的小提琴示例.

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

我在这做错了什么?

Jef*_*f B 6

你所相信的是正确的,除了当你分开时delKnob,你的鼠标会立即进入li包含它的鼠标,这意味着它会重新附着,所以当它li被移除时,delKnob仍然是一个孩子,因此被移除好.

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

this.cart.on('mouseenter', 'li', function () {
    console.log("delKnob attached!");
    delKnob.appendTo(this);
})
Run Code Online (Sandbox Code Playgroud)

通过删除解决这个问题delKnobsetTimeout:

setTimeout(function () {
    li.find('.delKnob').detach();
    li.remove();
}, 500);
Run Code Online (Sandbox Code Playgroud)

这假设将类添加delKnob到元素.

演示:http://jsfiddle.net/AHjRN/

作为一个方面说明,我将简化整个事情,只需添加一个delKnob到每个li.然后你只是显示/隐藏它们,而不必担心删除处理程序.它还简化了代码:

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();
      });   
};
Run Code Online (Sandbox Code Playgroud)

演示:http://jsfiddle.net/F3Qdp/