2012-05-22 7 views
5

ツールチップをトリガするmouseoverイベントがあります。このツールチップは、マウスを離すと消えてしまいます。 onmouseoutはうまく動作し、以外はを除きます。ここで要素がなくなったときに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ハンドラとremoveハンドラは動的に生成され、お互いを知る必要があります。さらに複雑なことに、リムーバブル要素が互いにネストされ、それらの要素のいずれかが削除される可能性があります。 (私はこの制約を取り除くことができるかもしれないが、それは少し仕事がかかります。)ここで


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

onremovedfromdocumentイベントを実装できる場合、onmouseoutハンドラをonremovedfromdocumentイベントとしてコピーするだけで、この例も正しく動作します。 (私はjQueryがこれをサポートしていると聞いていますが、非jQueryコードと相互運用する必要があります)。

各モーダルダイアログを繰り返しポーリングし、その親がドキュメントにあるかどうかを確認します。そうでないときは、セプクをコミットしてください。しかし、ポーリングは本当に醜いです。 (これ以上何もないのであれば、これをするつもりだと思います)

イベントキャプチャを使用してonmouseout要素がクリック要素を最初に取得できるようにし、タイマーがまだ存在するかどうかを確認するように設定しますクリックが完了した後の文書で


参考までに、私が実際にやっていることをここに示します。複雑なツリー構造を構築するJSウィジェットがあります。ウィジェットの編集の多くは、ツリー内のいくつかのボタンをクリックして、ツリーを追加または削除します(おそらくそれ自体を削除します)。しかし、ノードの中には複雑な編集手順が必要なものがあります。ユーザーがそれらの上にマウスを置いたときに指示や、もっと多くのボタンが表示されたり、ユーザーがクリックした場合に対話を維持することさえできます。しかし、ユーザは自分の心を変えて、ノードまたはノードの親を削除することを決定することができ、この場合、ダイアログは消えるべきである。私は現在、ダイアログが手動で作成されているhereの実装を見ることができます。素敵なツールチップライブラリを使いたいと思いますが、それらのすべてに上記で説明したバグがあります。

+0

対応する開封品がないときに、「」タグを閉じる理由がありますか?あなたのスパンも無効なhtmlです。閉鎖期間が必要です。 – Daedalus

+0

申し訳ありませんが、それはタイプミスでした。 –

+0

あなたのスパンは引き続き無効なhtmlです。 は存在しません。 – Daedalus

答えて

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> 

+0

このソリューションはモジュール性テストに失敗します。バーの中に複数のonmouseoutハンドラがある場合はどうなりますか? –

+0

私はonmouseouteventが呼び出されていると思いました。代わりに、背景色を直接変更することもできます。私はこれを編集しました。 –

+0

あなたの編集は、**文書**の背景が変更されたことを考慮して、問題を解決するものではありません。 'div' **バー**の内容ではありません。 – Daedalus

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です。

+0

ニース!ブラウザが近代的でなければならないことをあなたは知っていますか?編集:再、廃止、それは吸う! –

+0

IE9、Chrome、Firefoxで動作すると読んでいます - http://stackoverflow.com/a/6987471/825789を参照してください。 – bfavaretto

+0

奇妙なことに、何らかの理由で、これは完全な例では機能しません。何故かはわからない。 –

関連する問題