当元素消失时,onmouseout不会被触发

时间:2012-05-22 22:25:01

标签: javascript javascript-events

我有一个鼠标悬停事件触发工具提示;我希望这个工具提示在移除鼠标时消失。当元素消失时,onmouseout效果很好,除了

这是一个使用背景更改而不是工具提示的简化示例(因此您可以轻松地运行它):

<div id="bar">
  <div onmouseover="document.bgColor='gray'" onmouseout="document.bgColor='white'" style="border:1px solid black;">
   <span onclick="document.getElementById('bar').innerHTML = ''">Remove me</span>
  </div>
</div>

问题在于:当我点击“删除我”时,我的鼠标不再“超过”div,但是onmouseout不会触发,因为它已经消失了。我想要的是这个例子在我点击“删除我”时恢复到白色背景。

有一个明显的解决方案,我想避免。我不希望删除元素的onclick处理程序手动“修复”文档。这是因为可能有任意多个处理程序可以使用onmouseout删除div。通常,所有鼠标移除和移除处理程序可以动态生成,并且需要彼此了解。为了使事情进一步复杂化,我可能会遇到可移动元素彼此嵌套的情况,并且可以删除其中的任何元素。 (我可能会删除此约束,但这需要一些工作。)


以下是一个可行的解决方案示例:在鼠标悬停时,将模态对话注册为“活动”;然后每当删除元素时,迭代所有模态对话并查找不再在文档中的对话框。但这需要我保持对话的全局存储,并花费时间O(n * m),其中n是活动对话的数量,m是对话在DOM中的深度嵌套。此外,每当我删除元素时,我都需要运行此操作,即使它很明显没有任何影响。

这是另一个可行的解决方案:如果你可以实现onremovedfromdocument事件,那么我们只需将onmouseout处理程序复制为onremovedfromdocument事件,该示例也将正常工作。 (我听说jQuery可能支持这个,但我需要与非jQuery代码进行互操作。)

这是另一种可能的解决方案:让每个模态对话重复轮询以查看其父级是否在文档中。如果不是,请让它承诺seppuku。但民意调查真的很难看。 (如果没有什么更好的话,我想我会愿意这样做!)

这是另一个想法:使用事件捕获来允许onmouseout元素首先捕获click元素,并设置一个计时器以在点击完成后检查它是否仍在文档中。


供参考,这是我真正想要做的:我有一个JS小部件,它构建了一个复杂的树结构。对窗口小部件的许多编辑涉及单击树中的某个按钮,然后从树中添加或删除(可能删除自身。)但是,某些节点需要更复杂的编辑过程,所以我想提出一个工具提示当用户将鼠标悬停在指令上时,可以使用说明和可能的更多按钮,甚至在用户点击它们时保持对话。但是用户可能会改变主意并决定删除节点或节点的任何父节点,在这种情况下对话应该消失。您可以查看我目前拥有的here实现,其中对话框是手动创建的。我想开始使用一个漂亮的工具提示库,但所有这些都有我上面描述的错误。

2 个答案:

答案 0 :(得分:2)

在现代浏览器中,有DOMNodeRemoved事件。所以:

var div = document.getElementsByTagName('div')[0];
div.addEventListener('DOMNodeRemoved', function(e){
    document.bgColor='white';
});​

http://jsfiddle.net/HX88L/

糟糕的是,该事件已经deprecated。替换所谓的mutation events似乎还没有准备好使用它。 MDN文档页面仍然只是stub

答案 1 :(得分:0)

尝试:

    <script>
    var liveToolTip = new Array();
    function addLiveToolTip(elName){
        if(elName in liveToolTip){
        }else{
            liveToolTip[elName]=1;}
    }
    function removeLiveToolTip(elName){
        if(elName in liveToolTip){
            delete liveToolTip[elName];
        }
    }
    function runOnMouseOuts() {
        for(mouseOut in liveToolTip) {
            document.getElementById(mouseOut).onmouseout();
        }
    }
</script>
<div id="bar">
  <div onmouseover="addLiveToolTip(this.id);document.bgColor='gray'" 
        onmouseout="removeLiveToolTip(this.id);document.bgColor='white'" style="border:1px solid black;" id="foo">
      <span onclick="document.getElementById('bar').innerHTML = '';runOnMouseOuts()">
      Remove me</span>
  </div>