6

我有一个触发工具提示的鼠标悬停事件;我希望这个工具提示在鼠标被移除时消失。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。通常,所有的 mouseout 和删除处理程序都可能是动态生成的,并且需要相互了解。更复杂的是,我可能会遇到可移动元素相互嵌套的情况,并且它们中的任何一个都可以被删除。(我也许可以删除这个约束,但需要做一些工作。)


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

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

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

这里还有一个思路:使用事件捕获让onmouseout元素先捕获click元素,并设置一个定时器来检查点击完成后它是否还在文档中。


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

4

2 回答 2

2

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

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

http://jsfiddle.net/HX88L/

不好的是,那个事件已经被弃用了。所谓的突变事件的替代品看起来还没有准备好使用。MDN 文档页面仍然只是一个存根

于 2012-05-22T22:54:24.977 回答
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>

于 2012-05-22T22:41:19.263 回答