Событие 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. Я не видел проблем с этим, если кто-то не может думать ни о чем.