4

示例小提琴

JavaScript

$('#btn').on('mouseover', function() {
    $('#tt').show();
}).on('mouseleave', function() {
    $('#tt').hide();
}).on('click', function() {
    $(this).remove();
});

HTML

<button id="btn">press me</button>
<div id="tt">tooltip</div>

基本上,当您在光标仍在其上方时移除元素时,该mouseleave事件永远不会触发。我想这是有道理的,因为如果元素消失了,事件/绑定也消失了。

但是我们如何解决它呢?

当然,我也可以$('#tt').hide();参加这个click活动,但我希望有一个更通用的解决方案。我在现实生活中的例子要复杂一些,而且我并不总是知道元素什么时候会被移除。

没有任何ondestroy事件或任何我可以挂钩的东西,它会在它被移除之前触发,是吗?

4

1 回答 1

2

我已使用此解决方案中的代码更新了您的jsFiddle

(function($){
  $.event.special.destroyed = {
    remove: function(o) {
      if (o.handler) {
        o.handler()
      }
    }
  }
})(jQuery)

$('#btn').on('mouseover', function() {
  $('#tt').show();
}).on('mouseleave', function() {
  $('#tt').hide();
}).on('click', function() {
  $(this).remove();
}).on('destroyed', function() {
  $('#tt').hide();
})

或者,您可以绑定到 DOMNodeRemoved 突变事件,但W3 规范指出,由于性能和跨浏览器支持问题,不推荐使用此事件类型。

$(document).bind('DOMNodeRemoved', function(e) {
  if(e.target.id=='btn') {
    $('#tt').hide();
  }
});

在较新的浏览器(Chrome 18+、Firefox 14+)中,支持MutationObserver对象,该对象旨在替换突变事件。在您的情况下,它可以这样工作:

var target = document.querySelector('body');

var observer = new MutationObserver(function(mutations) {
  mutations.forEach(function(mutation) {  
    if(mutation.removedNodes[0]!=undefined) {
      if(mutation.removedNodes[0].id=='btn') {
        $('#tt').hide();              
      }
    }
  });    
});

var config = { attributes: true, childList: true, characterData: true };

observer.observe(target, config);

这是Code Review 上一个问题的链接,其中有人正在编写一个 DOM MutationObserver shim,当 MutationObserver 对象不可用时,它会依赖于突变事件。

于 2013-04-17T02:20:46.940 回答