3

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

单击该元素时,它会被分离,然后它所在的列表项会从 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>

还有我的 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');

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

问题是该元素的单击侦听器也与列表项一起被删除,即使该元素在$.remove()触发前被分离,所以它不应该受到影响。

我在这里做错了什么?

4

2 回答 2

6

您认为正在发生的事情是正确的,除了当您分离 时delKnob,您的鼠标会立即进入li包含它的那个,这意味着它会被重新连接,所以当它li被移除时,delKnob它仍然是一个孩子,因此被移除为出色地。

我通过console.log()在代码中添加 a 对此进行了测试:

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

通过删除以下内容来解决此delKnob问题setTimeout

setTimeout(function () {
    li.find('.delKnob').detach();
    li.remove();
}, 500);

这假设将类添加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();
      });   
};

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

于 2013-06-12T20:25:42.950 回答
1

您可以使用事件委托并将事件绑定到处理任何被单击的后代的容器(),而不是将事件绑定到delKnob(重新)移动的事件。this.cart.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);
  });

演示

于 2013-06-12T20:27:11.263 回答