.mouseleave() с .delay() работают вместе

У меня есть список из нескольких «триггеров» (<li>s), каждый триггер показывает определенный DIV, и у каждого DIV есть кнопка «закрыть».

Теперь я хочу улучшить удобство использования, добавив таймер/задержку к открытому/видимому DIV, чтобы через 3 или 5 секунд после того, как пользователь отвел мышь от триггера, открытый/видимый DIV исчез.

Проблема, с которой я сталкиваюсь сейчас, заключается в том, что всякий раз, когда я добавляю функцию с помощью .mouseleave(), открытый/видимый DIV скрывается, как только мышь покидает область триггера.

Однако, если вы удалите функцию, DIV останется видимым, и вы сможете закрыть его, нажав кнопку закрытия.

Вот FIDDLE/DEMO моей ситуации.

Любая помощь будет принята с благодарностью.

Спасибо.


person Ricardo Zea    schedule 06.06.2011    source источник


Ответы (3)


Ответ @locrizak правильный (+1). Это связано с тем, что .delay() по умолчанию использует очередь эффектов, а .hide() без параметров скрывает выбранные элементы без каких-либо эффектов, поэтому очередь эффектов вообще не задействована.

Если вы хотите скрыть без анимации, просто используйте setTimeout:

$('.trigger').mouseleave(function() {
    setTimeout(function () {
        $('.copy .wrapper').hide();
    }, 3000);
});

http://jsfiddle.net/mattball/93F3k/


Последнее редактирование, обещаю

//Show-Hide divs
var current;
$('.trigger').live('mouseenter', function() {    
    var id = current = $(this).data('code');
    $('#' + id).show().siblings().fadeOut();
}).live('mouseleave', function() {
    var id = $(this).data('code');
    current = null;
    setTimeout(function ()
    {
        if (current !== id) $('#' + id).hide(1);
    }, 3000);
});

//Close button
$('.copy .wrapper span').live('click', function() {
    $(this).closest('.wrapper').stop(true, true).fadeOut();
});

Демонстрация: http://jsfiddle.net/mattball/b2ew5/

person Matt Ball    schedule 06.06.2011
comment
Мэтт, спасибо. Я использовал вашу функцию setTimeout, но она не сработала, хотя я не был уверен, должен ли я помещать ее внутрь $('.trigger').hover(function() или снаружи. Tnx. - person Ricardo Zea; 06.06.2011
comment
Я не понимаю твоего замешательства. Вы смотрели на jsFiddle? - person Matt Ball; 06.06.2011
comment
Работает почти на 100%. Проблема в том, что если вы наведете курсор на следующий элемент после того, как сначала навели курсор на другой, но начальная оболочка еще не исчезла, тогда обе оболочки исчезнут одновременно, и после этого, если вы наведете курсор на любой триггер, его соответствующая оболочка исчезает по прошествии секунды, даже если вы оставите указатель мыши над триггером. Спасибо. - person Ricardo Zea; 08.06.2011
comment
Что-то другое. Просто наведите курсор вверх и вниз на все триггеры, и вы поймете, что я имею в виду. - person Ricardo Zea; 08.06.2011
comment
Смотрите мою правку, что вы думаете? Вы хотите, чтобы другие элементы .copy .wrapper немедленно скрывались при наведении указателя мыши на другой элемент .trigger? вот так: jsfiddle.net/mattball/T6YUp/1 - person Matt Ball; 08.06.2011
comment
Да, это правильно, Мэтт. Любой другой видимый .wrapper должен немедленно скрыться, что и происходит в вашем примере. Однако там все равно есть 2 проблемы: 1. Наведение вверх-вниз по триггерам приводит к исчезновению оберток через секунду после выхода из триггерного элемента. И 2. Кнопка «Закрыть» не закрывает .wrapper. Tnx. - person Ricardo Zea; 08.06.2011
comment
Позвольте мне добавить, что проблема № 1 возникает случайным образом, вам просто нужно наводить курсор вверх и вниз, и в какой-то момент вы увидите, что .wrapper исчезает почти сразу после выхода из .trigger, когда это должно произойти через 3 секунды. Tnx снова. - person Ricardo Zea; 08.06.2011
comment
Кстати, не вызывайте .click() внутри .hover(), так как это будет каждый раз перепривязывать обработчик click. - person Matt Ball; 08.06.2011
comment
Привет, Мэтт, твой пример отлично сработал! Это именно то, что мне было нужно. Большое спасибо за ваше время и совет. Да, теперь, когда я смотрю на это, я не вижу необходимости вызывать .click() внутри .hover(). Tnx снова! - person Ricardo Zea; 08.06.2011
comment
Привет, Мэтт... это я или по какой-то причине обертки теперь вообще не прячутся в твоем примере? Я тоже пытался перезагрузить страницу, но ничего. о_О - person Ricardo Zea; 08.06.2011
comment
Вы правы, это потому, что я переключился с .hover(...) на .live('hover', ...), но не правильно написал обратный вызов. Я такой дурак! Во всяком случае, теперь это исправлено, смотрите правку. - person Matt Ball; 08.06.2011
comment
Абсолютно идеально! Tnx снова Мэтт :) - person Ricardo Zea; 08.06.2011
comment
Эй, Мэтт, ты собираешься убить меня ^_^, но у меня есть небольшая проблема: опять же, если вы наводите и выходите очень быстро и несколько раз над триггерами, а затем останавливаетесь и просто наводите курсор на любой триггер, обертка появляется, но затем скрывается, даже если ваша мышь находится над триггером. Амиго Мэтт, ты уже потратил много времени на это, если ты не хочешь больше возиться с этим, не беспокойся, все круто, я полностью понимаю. Я хотел бы быть более полезным, чем просто устранение неполадок, но, как вы видите, я еще не так хорошо разбираюсь в jQuery. Tnx снова. - person Ricardo Zea; 08.06.2011
comment
Хм, не думаю, что смогу воспроизвести проблему, но предположу. Это работает лучше для вас? jsfiddle.net/mattball/b2ew5 - person Matt Ball; 08.06.2011
comment
Да, как-то избавился от проблемы. Спасибо большое :) - person Ricardo Zea; 09.06.2011

Используйте setTimeout вместо delay.

Рабочая демонстрация: http://jsfiddle.net/J7qTy/

Из документации по задержке jQuery:

Метод .delay() лучше всего подходит для задержки между эффектами jQuery в очереди. Поскольку он ограничен — он, например, не предлагает способ отменить задержку — .delay() не является заменой родной функции JavaScript setTimeout, которая может быть более подходящей для определенных случаев использования.

person marcosfromero    schedule 06.06.2011
comment
marcosfromero, та же проблема, о которой я упоминал в посте Мэтта. Спасибо. - person Ricardo Zea; 08.06.2011

вам нужна продолжительность в укрытии:

$('.copy .wrapper').delay(3000).hide('fast');

Вы можете ознакомиться с документацией http://api.jquery.com/delay/.

Обновить

это то, что вы ищете?

$('.trigger').bind("mouseenter" , function() {    
    var id = $(this).attr("data-code"); // Get the data from the hovered element
    $('.copy .wrapper:visible').fadeOut();
    $('#' + id).stop(true, true).show(); // Toggle the correct div    
    //Close button
    $('.copy .wrapper span').click(function() {
        $('.copy .wrapper').fadeOut();
    });
});

Вот и избавьтесь от слушателя mouseleave

person locrizak    schedule 06.06.2011
comment
Локризак, спасибо. Однако, несмотря на то, что видимый элемент DIV скрывается на экране мыши, кнопка «закрыть» не работает. то есть: jsfiddle.net/rzea/8gWJM/3. Я проверил документацию jQuery .delay(), но я НЕ ТАК хорошо разбираюсь в JS. - person Ricardo Zea; 06.06.2011