JQuery зависания зависит от двух элементов - PullRequest
6 голосов
/ 26 мая 2011

У меня есть основная навигация и суб навигация, которые по причинам дизайна находятся в отдельных DIV.Я хотел бы показать соответствующую суб-навигацию при наведении основного навигационного элемента, что я могу сделать, но я также хочу оставить суб-навигацию открытой, если пользователь перемещает свою мышь вне основного навигационного элемента и в суб.-нав области.Последняя часть - это место, где я застреваю.

Я думаю о зависании, мне нужно что-то сделать с setTimeout () и оператором IF, но я не смог ничегопрогресс в этой области.Это даже подход стоит попробовать?

HTML:

<div id="mnav">
 <ul id="buttons">
  <li class="one"><a href="#">Main 1</a></li>
  <li class="two"><a href="#">Main 2</a></li>
  <li class="three"><a href="#">Main 3</a></li>
  <li class="four nav-dark"><a href="#">Main 4</a></li>
 </ul>
</div> <!-- /mnav -->

<div id="snav">
 <ul class="snav-one">
    <li><a href="#">Sub 1.1</a></li>
    <li><a href="#">Sub 1.2</a></li>
    <li><a href="#">Sub 1.3</a></li>
    <li><a href="#">Sub 1.4</a></li>
    <li><a href="#">Sub 1.5</a></li>
    <li><a href="#">Sub 1.6</a></li>
 </ul>
 <ul class="snav-two">
    <li><a href="#">Sub 2.1</a></li>
    <li><a href="#">Sub 2.2</a></li>
 </ul>
</div> <!-- /snav -->

JS:

$(document).ready(function() {
 $("#buttons li.one, #buttons li.two").hover(function(){
  var subnav = 'ul.snav-' + $(this).attr('class');

  $("#snav").slideDown('fast').addClass("open").find(subnav).show();

 }, function(e){
  var subnav = 'ul.snav-' + $(this).attr('class');

  $("#snav").slideUp('fast').removeClass("open").find(subnav).hide();
 });
});

Ответы [ 3 ]

8 голосов
/ 26 мая 2011

Для эргономики меню мыши требуется небольшая задержка при переходе от главного меню к подменю, поэтому подменю не закрывается до того, как мышь попадет туда. (Как гласит вопрос.)

Но вам также потребуется задержка перед открытием меню - и во избежание раздражающей активации "эстакады", и для уменьшения общего количества случайного переключения с sub1 на sub2 во время выход из главного меню.

Итак, коду вопроса нужно:

  1. hover над подменю ul элементов.
  2. stop для остановки анимации при изменении выбора мыши.
  3. Сбрасываемый таймер, управляющий как открытием, так и закрытием.

См. Демонстрацию на jsFiddle .

Собираем все вместе:

$("#buttons li.one, #buttons li.two").hover ( function () { MenuOpenCloseErgoTimer (
        100,
        function (node) {
            var subnav = 'ul.snav-' + $(node).attr ('class');
            $("#snav ul").hide ();
            $("#snav").stop (true, true).slideDown ('fast').addClass ("open").find (subnav).show ();
        },
        this
    ); },
    function () { MenuOpenCloseErgoTimer (
        200,
        function () {
            $("#snav").stop (true, true).slideUp ('fast').removeClass ("open").find ('ul').hide ();
        }
    ); }
);

$("div#snav ul").hover ( function () { MenuOpenCloseErgoTimer (
        0,
        function () {
            $("#snav").stop (true, true).slideDown ('fast').addClass ("open");
            $(this).show ();
        }
    ); },
    function () { MenuOpenCloseErgoTimer (
        200,
        function () {
            $("#snav").stop (true, true).slideUp ('fast').removeClass ("open");
            $("#snav ul").hide ();
        }
    ); }
);

function MenuOpenCloseErgoTimer (dDelay, fActionFunction, node) {
    if (typeof this.delayTimer == "number") {
        clearTimeout (this.delayTimer);
        this.delayTimer = '';
    }
    if (node)
        this.delayTimer     = setTimeout (function() { fActionFunction (node); }, dDelay);
    else
        this.delayTimer     = setTimeout (function() { fActionFunction (); }, dDelay);
}



Обратите внимание на дополнительные операции, необходимые для #snav ul, для очистки после прерванных перестановок между подменю.

4 голосов
/ 26 мая 2011

Вместо использования метода .hover () попробуйте использовать отдельные обработчики событий для mouseenter и mouseleave. Мышиный указатель будет привязан только к кнопкам mnav, а указатель мыши будет привязан как к кнопке mnav, так и к элементу snav. В ваших функциях отпускания мыши вам, вероятно, придется добавить небольшой тайм-аут и проверить, перешли ли они с одного элемента на другой.

Попробуйте что-то вроде этого:

<script>
    var timer;
    $(document).ready(function() {
        $("#mnav").mouseenter(function() {
            $("#snav").slideDown();
        });

        $("#mnav, #snav").mouseleave(function() {
            timer=setTimeout("$('#snav').slideUp();",50);
        });

        $("#mnav, #snav").mouseenter(function() {
            clearTimeout(timer);
        });
    });
</script>
1 голос
/ 26 мая 2011

См. Пример & # x2192;

Следующее должно работать для вас, я сделал несколько изменений:

  • использовал .stop() метод , чтобы остановить анимацию при входе в субнап
  • переместил слайды в поднавал, а не в контейнер, чтобы вышеприведенное сработало
  • некоторые другие вещи

См. Ниже:

$("#buttons li.one, #buttons li.two").hover(function() {
    var subnav = 'ul.snav-' + $(this).attr('class');

    $("#snav").find('ul').slideUp('fast');
    $("#snav").addClass("open").find(subnav).stop(true, true).slideDown('fast');
}, function(e) {
    var subnav = 'ul.snav-' + $(this).attr('class');

    $("#snav").removeClass("open").find(subnav).slideUp('fast');
});

$('#snav').bind('mouseenter', function(e) {
    $(this).find('ul').stop(true, false);
}).bind('mouseleave', function(e) {
    $(this).find('ul').stop(true, true).slideUp('fast');
});

См. Пример & # x2192;

...