Jquery hover меняет задержку, скрывающуюся при отпускании мыши, но останавливает скрытие, если мышь входит раньше установленного времени - PullRequest
0 голосов
/ 26 февраля 2012

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

Редактировать: вот ссылка на jsfiddle для полного примера

Редактировать: 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 () {
            });

 });

Хорошо, это то, чем я закончил.но нельзя ли сделать это с меньшим количеством кода?

Редактировать: 6 Ссылка jsfiddle теперь обновлена ​​до последней версии.

Ответы [ 2 ]

0 голосов
/ 26 февраля 2012

Взгляните на плагин hoverIntent.Все, что вам нужно сделать, это включить его и изменить метод «hover» на «hoverIntent»

http://cherne.net/brian/resources/jquery.hoverIntent.html

0 голосов
/ 26 февраля 2012

Попробуйте использовать focusout() с delay(). Кроме того, я не думаю, что вам нужна вся эта if else логика. Каждое подменю - это <ul> дочерние элементы $('#menu') и в то же время дочерние элементы <li>, поэтому вы можете легко создать функцию для отображения или скрытия меню, которое принимает объект jQuery в качестве параметра. Без вашего HTML-кода я не могу сказать наверняка, но что-то вроде этого должно работать. Адаптируйся к своим потребностям.

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

Также это:

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

совпадает с:

element.is(':visible')
...