6

ドロップダウンメニューのキーボードにアクセスできるようにするためのロジックを理解することに固執しています。

HTML は次のように構成されています (わかりやすくするために追加のクラス名が使用されています)。

<ul>
    <li class="primaryMenuItem">
        <a href="">Link 1</a>
        <ul class="popUpMenu">
            <li><a href="">Sub Link 1</a></li>
            <li><a href="">Sub Link 2</a></li>
        </ul>
    </li>
    <li class="primaryMenuItem">
        <a href="">Link 2</a>
        <ul class="popUpMenu">
            <li><a href="">Sub Link 1</a></li>
            <li><a href="">Sub Link 2</a></li>
        </ul>
    </li>    
</ul>

リンク 1 とリンク 2 をホバーすると、サブメニュー リスト (プルダウン メニュー) が表示されます。これは、いくつかのjQueryとjQuery hoverIntentプラグインでうまく機能しています。

キャッチは、これが現時点でマウスでのみ機能することです。

次の課題は、これをキーボードで動作させることです。

トップ レベルのリンクにフォーカス イベントを簡単に追加して、セカンダリ メニューをトリガーすることができます。

$('ul.primaryMenuItem a:first').focus([call showMenu function]) 

それはうまくいきます。

メニューを閉じる方法の 1 つは、別のメニューを開くときに、別のメニューが既に開いているかどうかを確認し、開いている場合は閉じることです。

それもうまくいきます。

ただし、それが失敗するのは、最後のメニューを開いてタブから抜けた場合です。別のメニューにタブ移動していないため、このメニューは開いたままです。

課題は、メニューを閉じる方法/タイミングと、それを把握するために必要なロジック (jQuery) を把握することです。理想的には、メニューの子要素以外のページ上の要素にフォーカスがある場合は、メニューを閉じます。

論理的に、私はこれを探しています:

$('li.primaryMenuItem').blur([close $(this).find('ul.popUpMenu'))

ただし、LI には実際にはフォーカスがなく、その中のアンカー タグがあるため、それはできません。

助言がありますか?

アップデート:

おそらく、質問をするためのより良い/簡単な方法:

jQuery経由で、フォーカスが特定のオブジェクトのすべての子の外に移動したかどうかを「監視」する方法はありますか?

4

7 に答える 7

6

イベントバブリングを使用して、focusinイベントにフォーカスしているものを確認できます。私は次のコードで成功しました:


$("li:has(ul.popUpMenu)").focusin(function(e) {
    $(this).children().fadeIn('slow');
  });
  $('body').focusin(function(e) {
    if (!$(e.target).parent().is('ul.popUpMenu li')) {
      $('ul.popUpMenu').fadeOut('slow');
    }
  });

おそらくそれをより最適化することができます(すべきです)が、それは機能します。

于 2010-02-04T00:06:44.307 に答える
2

以下のようにしたらどうでしょう。

$('#link_A_id, #link_A_id > *').focusout(function () {
    if ($(document.activeElement).closest('#link_A_id').length == 0)
        //focus is out of link A and it's children
});
于 2012-01-12T03:02:21.977 に答える
2

新しい jquery 1.4 関数: focusinandfocusoutの代わりにblurand を使用しfocusます。focusout違いは次のとおりです。

focusout イベントは、要素またはその中の要素がフォーカスを失うと、その要素に送信されます。これは、親要素からのフォーカスの喪失の検出をサポートするという点で、blur イベントとは異なります (つまり、イベントのバブリングをサポートします)。

于 2010-02-03T22:35:53.377 に答える
0

これは私を助けました... http://plugins.jquery.com/project/focus

あなたがまだ親の中にいるかどうかを自動的に検出します。それは基本的に jQuery focusout を代わりにこのように動作するように変更します。

<div class="parent">
   <input type="text" />
   <input type="text" />
</div>

$('#parent').focusout(function () {
    console.log('focusout of parent');
});

タブを押してテキストフィールドを子要素間で移動すると、親のフォーカスアウトがトリガーされる理由がわかりません。なぜなら、あなたはまだその親の中にいるからです。何かが起こっているに違いないので、しばらくの間、それはバグだと思います... 誰か私と一緒にいますか? とにかく、上記のプラグインはそれを修正します。これを「修正」するには、コードの前に含めるだけです。そうでない場合、これがバグではない理由を誰かに説明してもらいたいです。

ありがとう、ドム

于 2011-09-12T09:40:17.227 に答える
0

これを試して

$('li.primaryMenuItem:last li a:last').blur([do whatever you need to do])

論理的には、ユーザーがタブアウトした場合、最後のアンカーにフォーカスしていたに違いありません。

次のように、独自のイベント ハンドラーを設定することもできます。

$('li.primaryMenuItem:last').bind('myblur', function() ...);

最後のアンカー ブラー イベント内で呼び出します。

...blur(function() {
    $(this).parents('li.primaryMenuItem').trigger('myblur'); ...
于 2010-02-03T23:00:11.197 に答える