Событие Blur перестает кликать событие из работы?
Похоже, что событие Blur прекращает работу обработчика событий кликов? У меня есть поле со списком, в котором параметры отображаются только в том случае, если текстовое поле имеет фокус. Выбор ссылки опции должен вызвать событие.
У меня есть пример скрипки: http://jsfiddle.net/uXq5p/6/
Воспроизведение:
- Выберите текстовое поле
- Появятся ссылки
- Нажмите ссылку
- Размытие даже происходит, и ссылки исчезают
- Ничего другого не происходит.
Ожидаемое поведение:
На шаге 5 после размытия щелчок должен также загореться. Как это сделать?
UPDATE:
Поиграв с этим какое-то время, кажется, что кто-то прошел долгий путь, чтобы предотвратить обработку уже произошедшего события клика, если событие размытия делает элемент clicked Un-clickable.
Например:
$('#ShippingGroupListWrapper').css('left','-20px');
работает отлично, но
$('#ShippingGroupListWrapper').css('left','-2000px');
предотвращает событие click.
Это, кажется, ошибка в Firefox, так как создание элемента un-clickable должно предотвращать клики будущих, но не отменять те, которые уже произошли, когда это может быть щелкнул.
Другие действия, препятствующие обработке события click:
$('#ShippingGroupListWrapper').css('z-index','-20');
$('#ShippingGroupListWrapper').css('display','none');
$('#ShippingGroupListWrapper').css('visibility','hidden');
$('#ShippingGroupListWrapper').css('opacity','.5');
Я нашел несколько других вопросов на этом сайте, которые имеют схожие проблемы. Кажется, что существуют два решения:
-
Используйте задержку. Это плохо, потому что это создает условие гонки между скрытием и обработчиком событий click. Его также неаккуратно.
-
Используйте событие mousedown
. Но это не отличное решение, так как click
- правильное событие для ссылки. Поведение mousedown
противоречит интуиции с точки зрения UX, тем более что вы не можете отменить клик, перемещая мышь от элемента до отпускания кнопки.
Я могу вспомнить еще несколько.
3.Используйте mouseover
и mouseout
в ссылке, чтобы включить/отключить событие размытия для поля. Это не работает с клавиатурой, поскольку мышь не задействована.
4. Лучшим решением будет что-то вроде:
$('#ShippingGroup').blur(function()
{
if($(document.activeElement) == $('.ShippingGroupLinkList'))
return; // The element that now has focus is a link, do nothing
$('#ShippingGroupListWrapper').css('display','none'); // hide it.
}
К сожалению, $(document.activeElement)
, кажется, всегда возвращает элемент body, а не тот, который был нажат. Но, может быть, если бы был надежный способ узнать, что 1. у какого элемента теперь есть фокус или два, этот элемент вызвал размытие (а не размытие элемента) внутри обработчика размытия. Кроме того, есть ли другое событие (кроме mousedown
), которое срабатывает перед размытием?
Ответы
Ответ 1
click
события запускаются после blur
, поэтому ссылка скрывается. Вместо click
используйте mousedown
, он будет работать.
$('.ShippingGroupLinkList').live("mousedown", function(e) {
alert('You wont see me if your cursor was in the text box');
});
Другой альтернативой является задержка, прежде чем вы спрячете ссылки на событии blur
. Его до вас, к которому нужно идти.
Демо
Ответ 2
Вы можете попробовать событие mousedown
вместо click
.
$('.ShippingGroupLinkList').live("mousedown", function(e) {
alert('You wont see me if your cursor was in the text box');
});
Это явно не лучшее решение, поскольку событие mousedown
не достигается таким же образом для пользователя, как событие click
. К сожалению, событие blur
также отменяет события mouseup
.
Ответ 3
Выполнение действия, которое должно произойти на click
на mousedown
плохо UX. Вместо этого, из чего фактически состоит click
? mousedown
и mouseup
.
Таким образом, остановить распространение на mousedown
событие в mousedown
обработчика, и выполнить действие в mouseup
обработчика.
Пример в ReactJS:
<a onMouseDown={e => e.preventDefault()}
onMouseUp={() => alert("CLICK")}>
Click me!
</a>
Ответ 4
4. Лучшим решением будет что-то вроде:
$('#ShippingGroup').blur(function()
{
if($(document.activeElement) == $('.ShippingGroupLinkList'))
return; // The element that now has focus is a link, do nothing
$('#ShippingGroupListWrapper').css('display','none'); // hide it.
}
К сожалению, $(document.activeElement), кажется, всегда возвращает элемент тела, а не тот, который был нажат. Но, возможно, если бы надежный способ узнать, какой 1. какой элемент теперь имеет фокус или два, этот элемент вызвал размытие (не размытие) внутри обработчика размытия.
То, что вы, возможно, ищете, - e.relatedTarget. Поэтому при нажатии ссылки e.relatedTarget
должен быть заполнен элементом ссылки, поэтому в вашем обработчике размытия вы можете не скрывать контейнер, если элемент, щелкнутый по нему, находится внутри контейнера (или сравнивает его напрямую со ссылкой):
$('#ShippingGroup').blur(function(e)
{
if(!e.relatedTarget || !e.currentTarget.contains(e.relatedTarget)) {
// Alt: (!e.relatedTarget || $(e.relatedTarget) == $('.ShippingGroupLinkList'))
$('#ShippingGroupListWrapper').css('display','none'); // hide it.
}
}
(relatedTarget
может не поддерживаться в старых браузерах для событий blur
, но, похоже, работает в последних браузерах Chrome, Firefox и Safari)
Ответ 5
Я знаю, что это более поздний ответ, но у меня была та же проблема, и многие из этих решений не работали в моем сценарии. mousedown
не работает с формами, это может привести к изменению функциональности клавиши ввода на кнопке отправки. Вместо этого вы можете установить переменную _mouseclick
true в mousedown
, проверить ее в blur
и preventDefault()
если оно true. Затем в mouseup
установите переменную false. Я не видел проблем с этим, если кто-то не может думать ни о чем.