2

関数と関数をhover使用してビューに出入りするウィジェットを作成しています。ただし、フォーカスされたフォーム要素が含まれている場合、ビューから滑り落ちないようにしたいので、これを行っています:showTrackerhideTracker

function hideTracker(){
  if($('#tracker').find(':focus').length == 0){ 
    $('#tracker').stop().hide();    
  }
}

涼しい。フォーカスのあるフィールドがある場合にマウスが外に出ても、非表示になりません。残念ながら、これは、フィールドがフォーカスを失った場合 (そして、ウィジェットが再び非表示になるとき) に、そこにとどまることも意味します。unHover イベントはなくなりました。

だから私はこれを追加しました:

$('#tracker *').blur(function(){
  hideTracker();
}); 

それもうまくいきます - 助けが必要な小さなバグが 1 つあります。

フォーカスがトラッカー内のある要素から 内にある別の要素に移動する#trackerと、トラッカーは非表示になります。次のフォーム要素にフォーカスがある場合、false が返されると思いましたif($('#tracker').find(':focus').length == 0)が、そうではないと思います。

次の要素がフォーカスを得る前に .blur() が発火するのは事実ですか?

どうすればこれを回避できますか?

4

3 に答える 3

1

Yikes. Tricky. Yes, what's happening is:

  1. mousedown: old form element gets the blur event. $(':focus').length == 0.
  2. mouseup: new form element gets the focus event. $newFormElement.is(':focus') == true.

This is an improvement:

$('#tracker').focusout(function() //basically like $('#tracker, #tracker *').blur(), but "this" is always '#tracker'
{
    if(!$(this).is('#tracker:hover')) //for some reason plain old :hover doesn't work, at least on the latest OS X Chrome
        hideTracker();
});

But it's not perfect. It only really works if you use the mouse. If you use tab to move between fields (or some other possible mechanism) while your mouse is not hovering over #tracker, it won't work.


Here's another attempt. It's a bit...hackier. The gist is that, instead of handling the blur event, you handle the focus event of the second thing that's focused. But! What if you click something that can't be focused? Blank space on your page? Then no focus event is fired.

Okay. So the trick is: put a tabindex="0" in your root <html> tag. This means that there is always something that can be focused. So there's no way to focus on nothing (at least, I don't think so).

Then you can do this:

$('*').live('focus', function(e)
{
    if(!$.contains($('#tracker')[0], this)) //if the new thing you focused on is not a descendant of #tracker
        hideTracker();
    e.stopPropagation();
});

Eh? So yeah, that's a certified hack. But it's a tough problem, and that's the best I can come up with at this hour.

于 2011-03-21T05:38:39.033 に答える
1

このようなものはどうですか?

$('body *').focus(function(){
    if(!$(this).is('#tracker *') && $('#tracker:visible').length != 0) hideTracker();
});
于 2011-03-21T04:46:04.480 に答える
0

回答ありがとうございます。.blur() ではなく .focus() イベントを利用することは、それを見る賢い方法でした。残念ながら、ブラウザの問題がいくつか発生し、上記のいずれも非常に安定して動作させることができませんでした。

最終的にsetTimeout(hideTracker, 100);、トラッカー内のフォーカスされた要素の数が評価される前に focus() イベントが発生するようにするために使用することにしました。理想的ではありませんが、うまく機能しており、遅延はほとんど感じられません。

再度、感謝します。

于 2011-03-23T01:06:54.123 に答える