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の「上」に表示されなくなりますが、マウスアウトが消えたため、オンマウスアウトはトリガーされません。この例では、[削除]をクリックすると白い背景に戻ります。

私が避けたい明らかな解決策があります。要素を削除するonclickハンドラーがドキュメントを手動で「修正」することは望ましくありません。これは、onmouseoutでdivを削除できるハンドラーが任意に多数存在する可能性があるためです。一般に、すべてのマウスアウトハンドラーと削除ハンドラーは動的に生成される可能性があり、お互いについて知る必要があります。さらに複雑なことに、リムーバブル要素が互いにネストされていて、それらのいずれかを削除できる場合があります。(この制約を取り除くことはできるかもしれませんが、少し手間がかかります。)


動作する可能性のあるソリューションの例を次に示します。マウスオーバーで、モーダルダイアログを「アクティブ」として登録します。次に、要素が削除されるたびに、すべてのモーダルダイアログを繰り返し処理し、ドキュメントに存在しなくなったダイアログを探します。ただし、これにはダイアログのグローバルストアを維持する必要があり、時間O(n * m)がかかります。ここで、nはアクティブなダイアログの数であり、mはダイアログがDOMにどれだけ深くネストされているかを示します。さらに、要素を削除するたびにこの操作を実行する必要があります。影響がないことは明らかですが。

動作する可能性のある別のソリューションを次に示します。onremovedfromdocumentイベントを実装できる場合は、onmouseoutハンドラーをonremovedfromdocumentイベントにコピーするだけで、例も正しく動作します。(jQueryはこれをサポートしていると聞きましたが、jQuery以外のコードと相互運用する必要があります。)

さらに別の可能な解決策があります。各モーダルダイアログを繰り返しポーリングして、その親がドキュメント内にあるかどうかを確認します。そうでない場合は、切腹してもらいます。しかし、ポーリングは本当に醜いです。(これ以上良いものがなければ、私は喜んでこれを行うと思います!)

別のアイデアは次のとおりです。イベントキャプチャを使用して、onmouseout要素が最初にクリック要素をキャプチャできるようにし、クリックが完了した後もドキュメント内に残っているかどうかを確認するタイマーを設定します。


参考までに、私が実際にやろうとしていることは次のとおりです。複雑なツリー構造を構築する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 doc ページはまだ単なるスタブです。

于 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 に答える