Javascript-форум (https://javascript.ru/forum/)
-   jQuery (https://javascript.ru/forum/jquery/)
-   -   отсрочить проверку отлавливания события (https://javascript.ru/forum/jquery/26514-otsrochit-proverku-otlavlivaniya-sobytiya.html)

Polkan 11.03.2012 13:42

отсрочить проверку отлавливания события
 
Здравствуйте.
Скажите, есть ли возможность как-то отсрочить отлавливание события (в моем случае, mouseleave)? Подчеркну, не срабатывания кода по данному событию, а именно факта его наступления. Чтобы выпадающее меню не закрывалось, если человек случайно на полсекунды вывел мышку из блока и вернулся назад.

Rootpassword 11.03.2012 13:45

Так, как вы сформулировали-нет, нельзя.

T-sh 11.03.2012 14:01

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

Polkan 11.03.2012 14:11

T-sh, я думал об этом, но непонятно как в этой функции проверять не вернулась ли мышь на блок меню. По координатам, конечно можно, но "костыльно" как-то это.

T-sh 11.03.2012 14:18

Цитата:

Сообщение от Polkan (Сообщение 162469)
T-sh, я думал об этом, но непонятно как в этой функции проверять не вернулась ли мышь на блок меню. По координатам, конечно можно, но "костыльно" как-то это.

ну, проверить, не вернулась ли мышь не так уж сложно :)
оборачивайте выпавшее меню div'ом и отслеживайте на нём событие.

получатся вложенные события:

с блока А ушла мышь{
на блок Б пришла мышь{ ничего не делать; остановить выполнение;}
иначе {скрыть}
}

T-sh 11.03.2012 14:23

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

Rootpassword 11.03.2012 14:26

вы можете по mouseleave вешать var interval=таймаут на 0.5 секунд на код, который меню закрывает, interval сохранить.
Если мышь вернулась-то есть это те события, по которым меню раскрывается, и если interval не null-тогда clearInterval(interval), что отменит складывание меню.
ничего сложного.

T-sh 11.03.2012 14:28

кстати, да. Rootpassword прав.

я тут совсем нелогичные костыли изобретаю.

Polkan 11.03.2012 15:29

Rootpassword, T-sh, спасибо за советы. Но пока не выходит. С clearTimeout загвоздка в том, что при перемещении по меню пункты с которых ушла мышь скрываются, одновременно те, на которые пришла - показываются. Все это обрабатывается двумя функциями - mouseleave и mouseenter. И получается, что, вешая на "те события, по которым меню раскрывается" clearTimeout, я решаю проблему со скрытием меню при выходе за границу, но получаю еще бОльшую - отменяю действие скрытия меню при перемещении с пункта на пункт.

Pavel M. 11.03.2012 15:29

у библиотек бывают, при назначении события, удобные опции
например в Ext есть параметр buffer: xxx милисекунд
если за это время было несколько событий mouseout, то вызовется только одно и можно закрывать меню или что-то другое
<script src="http://yandex.st/ext-core/3.1.0/ext-core.min.js"></script>

<div id="box" style="width: 100px; height: 100px; background: #cfc;"></div>

<script>
	Ext.get("box").on('mouseout', function (event, el) {
		alert('можно скрывать');
	}, this, {buffer: 1000});
</script>

Rootpassword 11.03.2012 15:37

так вы проще сделайте. если у вас не уход, а переход, то не таймаут, а мгновенное исполнение.

Polkan 11.03.2012 16:38

Цитата:

Сообщение от Rootpassword (Сообщение 162498)
так вы проще сделайте. если у вас не уход, а переход, то не таймаут, а мгновенное исполнение.

Ммм, но с точки зрения элементов-то это как определить? Есть блок: мышь пришла - событие mouseenter, мышь ушла - событие mouseleave. Откуда блок узнает ушла мышь вообще или перешла на другой блок?
Пробовал повесить на корневой контейнер такое:
$("#sidebarMenu").bind('mouseenter',function(){$("#sidebarMenu").attr('flagOver',1);});
$("#sidebarMenu").bind('mouseleave',function(){$("#sidebarMenu").attr('flagOver',0);});
Но при проверке этот флаг почему-то всегда оказывается единицей.
Хотя нет, не оказывается он единицей, меняется правильно, вот только уже после того, как мне его нужно проверять (по событию mouseleave для потомков)
Да и опять как-то криво это выглядит.

Rootpassword 11.03.2012 16:45

Ну так вы создаете таймер по событию ухода, в него вешаете функцию по закрытию, получаете intervalID=settimeout(500, func)
Дальше, грубо говоря, заводите массив, в него загоняете intervalID + func. Если окончательно ушли, через 0.5 секунды таймер вам меню свернет, массив почистит ваша func. Если же пришли на другой элемент, то чистим таймауты через cleanInterval и исполняем функции сразу, массив чистим.
Массив, а не переменные, на случай, если пользователь нервный и быстро мышку двигает.
Визуально будет как надо.

Polkan 11.03.2012 16:59

Rootpassword, спасибо за помощь, но, наверное, это просто выше моего понимания. :) Пусть пока остается по-старому.


Часовой пояс GMT +3, время: 20:30.