простой выпадающий JQuery - clearTimeout, setTimeout проблемы - PullRequest
3 голосов
/ 23 февраля 2010

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);
} 

У меня проблемы с таймаутом. В использовании, если я наведу курсор мыши на «Три», выпадающий список остается навсегда. если я наведу курсор мыши на «A», выпадающий список останется навсегда, но если я наведу курсор мыши на «B» или что-нибудь ниже, меню закроется на мне если вы раскомментируете "// alert (timeout);" это происходит для B, (и A), но время ожидания будет иметь значение. почему это? я думал, что clearTimeout обнулит переменную тайм-аута

Ответы [ 2 ]

5 голосов
/ 05 июня 2010

Вы можете упростить свой код в целом, используя .hover() и .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, это устанавливает тайм-аут на верхний уровень <li>, у каждого из них есть независимый таймер, и когда вы наводите указатель мыши на этот элемент, только его таймер очищен. Также .hover() использует mouseenter и mouseleave, а не mouseover и mouseout, разница в том, когда вы входите в ребенка или между детьми, mouseenter больше не срабатывает, а mouseleave не срабатывает на родителя <li>, о котором мы заботимся.

Вы можете проверить это с помощью демонстрационной ссылки выше, я также добавил подпункты в первое меню, чтобы продемонстрировать их независимость. Если у вас возник вопрос по поводу $.proxy, это значит, что this внутри этой анонимной функции тайм-аута ссылается на то, что я хочу (текущий this) ... элемент который должен быть закрыт после тайм-аута.

0 голосов
/ 23 февраля 2010

вы пытаетесь создать выпадающее меню? почему бы не использовать существующие плагины jquery для этого или еще лучше, выпадающее меню только для css вроде http://purecssmenu.com/?

...