3

HTML:

<ul class="topnav">
    <li><a href="#"><span>One</span></a></li>
    <li><a href="#"><span>Two</span></a></li>
    <li>
        <li><a href="#"><span>Three</span></a></li>
        <ul class="subnav">
            <li><a href="#">A</a></li>
            <li><a href="#">B</a></li>
            <li><a href="#">C</a></li>
        </ul>
    </li>
</ul>

jquery:

var timeout = null;

$(document).ready(function() {

    $("ul.topnav li").mouseover(function() {

        if (timeout) clearTimeout(timeout);

        $(this).find("ul.subnav").slideDown('fast').show();

    }).mouseout(function() {
        timeout = setTimeout(closemenu, 500);
    });

    // sub menu mouseovers keep dropdown open
    $("ul.subnav li").mouseover(function() {
        if (timeout) clearTimeout(timeout);
    }
    ).mouseout(function() {
        timeout = setTimeout(closemenu, 500);
        // alert(timeout);

    });

    // any click closes
    $(document).click(closemenu);
});

// Closes all open menus 
function closemenu() {
    $('ul.subnav:visible').hide();
    if (timeout) clearTimeout(timeout);
} 

タイムアウトに問題があります。使用中に「Three」にマウスオーバーすると、ドロップダウンは永久に表示されなくなります。「A」にマウスオーバーすると、ドロップダウンは永遠に表示されなくなりますが、「B」またはそれより下にマウスオーバーすると、メニューが閉じます。「//アラート(タイムアウト);」のコメントを外した場合 B、(およびA)のためにそこに到達しますが、タイムアウトには値があります。どうしてこれなの?clearTimeout がタイムアウト変数を無効にすると思いましたか?

4

2 に答える 2

5

次のよう.hover()に andを使用すると、コード全体を簡素化できます。.data()

$(function() {
  $("ul.topnav li").hover(function() {
    var timeout = $(this).data("timeout");
    if(timeout) clearTimeout(timeout);
    $(this).find("ul.subnav").slideDown('fast');
  }, function() {
      $(this).data("timeout", setTimeout($.proxy(function() {
          $(this).find("ul.subnav").slideUp();
      }, this), 500));
  });
  $(document).click(function() {
      $('ul.subnav:visible').hide();
  });
});​

ここで動作するデモを見ることができます

グローバル変数を共有する代わりに、これはトップレベルごとtimeoutにタイムアウトを設定し、それぞれに独立したタイマーがあり、その要素にカーソルを合わせると、そのタイマーのみがクリアされます。また、 andではなくandを使用します。違いは、子または子の間に入るとき、再び発火せず、関心のある親で発火しないことです。 <li>.hover()mouseentermouseleavemouseovermouseoutmouseentermouseleave<li>

上記のデモ リンクでこれをテストできます。独立していることを示すために、最初のメニューにもサブ項目を追加しました。$.proxyそこについて質問がある場合は、thisそのタイムアウト匿名関数の内部で、私が望むもの(現在のthis)を参照するだけです...タイムアウト後に閉じる必要がある要素。

于 2010-06-05T11:12:24.817 に答える
0

ドロップダウンメニューを作成しようとしていますか?そのために既存のjqueryプラグインを使用しないのはなぜですか、それでもなお、http://purecssmenu.com/のようなcssのみのドロップダウンメニューですか?

于 2010-02-23T05:07:20.063 に答える