Próbuję dodać opóźnienie, które działa w moim menu rozwijanym, jeśli osoba błędnie przesunie mysz poza menu. Próbowałem wielu rozwiązań znalezionych tutaj, ale żadne z nich nie działa.

Edytować: tutaj jest link do jsfiddle z kompletnym przykładem

Edycja: 5

$(function () {
            var slideDownTime = 400;
            var firstRun = true;

            var $menu = $('#menu'),
            $submenus = $menu.find('ul'),
            $items = $menu.find('li'),
            hide = function ($el, $instantHide) {
                if (!firstRun) {
                    if (!$instantHide) {
                        // force the menu item to show.
                        $el.css({ visibility: "visible", display: "block" });

                        var hideMenuId = setTimeout(function () {
                            $el.hide().css('visibility', 'hidden');
                        }, 5000);

                        $el.data('hideMenuId', hideMenuId);
                    } else {
                        $el.hide().css('visibility', 'hidden');
                    }
                } else {
                    $el.hide().css('visibility', 'hidden');
                }
            },
            show = function ($el) {
                clearTimeout($el.data('hideMenuId'));
                $el.css('visibility', 'visible').stop(1, 1).slideDown(slideDownTime);

                hide($el.parent().siblings().find("ul"), true); // <-- this line hides the other submenus if hovered.

                var singleLevel = $el.parent().find("ul > li:not(:has(ul)) > a");
                singleLevel.hover(function () {
                    hide($(this).closest("ul").children('li').not(this).find("ul"), true);
                }, function () {
                });

                firstRun = false;
            };

            $menu.focusout(hide($submenus));
            $items.hover(function () {
                show($(this).children('ul'));
            }, function () {
                hide($(this).children('ul'), false);
            });

             // find the root elemement level with no children.
             $menu.find("> li a").not("ul li ul a").not("li:has(ul) > a").hover(function () {
                  //hide the unwantend menu items.
                  hide($(this).closest("ul").children('li').not(this).find("ul"), true);
            }, function () {
            });

 });

Ok, na tym skończyłem. ale czy nie można tego zrobić za pomocą mniejszej ilości kodu?

Edycja: 6 Link jsfiddle został zaktualizowany do najnowszej wersji.

0
robgha01 26 luty 2012, 03:08

2 odpowiedzi

Najlepsza odpowiedź

Spróbuj użyć focusout() z delay(). Poza tym myślę, że nie potrzebujesz całej tej logiki if else. Każde podmenu to <ul> dzieci $('#menu') i jednocześnie dzieci <li>, więc możesz łatwo utworzyć funkcję pokazującą lub ukrywającą menu, które akceptuje obiekt jQuery jako parametr. Bez twojego kodu html nie jestem pewien, ale coś takiego powinno działać. Dostosuj się do swoich potrzeb.

var $menu = $('#menu'), // Assuming this is a `<ul>`
    $submenus = $menu.find('ul'),
    $items = $menu.find('li'),
    hide = function($el){ 
        $el.delay(500).hide().css('visibility', 'hidden'); 
    },
    show = function($el){ 
        $el.css('visibility', 'visible').stop(1, 1).slideDown(); 
    };

$menu.focusout(hide($submenus));
$items.hover(function(){
    show($(this).children('ul'));
}, function(){
    hide($(this).children('ul'));
});

Także to:

element.css('visibility') != "visible" && element.css('display') != "block"

Jest taki sam jak:

element.is(':visible')
0
elclanrs 26 luty 2012, 04:41

Spójrz na wtyczkę hoverIntent. Wszystko, co musisz zrobić, to dołączyć go i zmienić metodę „hover” na „hoverIntent”

http://cherne.net/brian/rosources/jquery.hoverintent.html.

0
charlietfl 26 luty 2012, 05:07