Определите, какое событие вызвало фокус?

Мне нужно определить, что вызвало событие фокуса.

В идеале я хочу различать щелчок, ввод с клавиатуры/вкладки и ручной (с помощью кода) триггер.

Как я могу это сделать?

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


person mpen    schedule 17.07.2011    source источник
comment
Попробуйте связать событие «наведение мыши» (или «щелчок»), и если оно срабатывает, установите какой-либо флаг мыши, а затем проверьте его в событии фокуса.   -  person spacevillain    schedule 18.07.2011
comment
@spacevillain: не может ли щелчок также запускаться кодом?   -  person PeeHaa    schedule 18.07.2011
comment
Как насчет «наведения мыши», за которым следует «щелчок»? Вы можете проверить, находятся ли координаты мыши в правильных границах. Некрасиво, но думаю должно работать. Для чего вам это нужно? :-)   -  person spacevillain    schedule 18.07.2011
comment
@spacevillain: функция автозаполнения. Я хочу, чтобы он открывался всякий раз, когда вы щелкаете элемент или переходите к элементу, а элемент пуст, или, если он был запущен с помощью кода, ничего не делайте.   -  person mpen    schedule 18.07.2011
comment
Не дубликат, но похожий: stackoverflow.com/questions/6674669/   -  person mu is too short    schedule 18.07.2011


Ответы (1)


Если фокус исходит от вызова $x.focus(), то у события не будет свойства originalEvent, потому что от браузера не было никакого события, поэтому:

if(ev.hasOwnProperty('originalEvent')) {
    // Focus event was manually triggered.
}

Чтобы различать события фокуса клавиатуры и мыши, вы можете попробовать привязать обработчик keydown ко всему остальному, чтобы обнаружить Tab или Shift-Tab, но это будет грубый взлом и вероятно, не надежный; например, на iPad вы не нажимаете Tab, чтобы перейти к следующему полю, вы нажимаете Далее или Назад во всплывающей клавиатуре. для перемещения, и они могут вообще не регистрироваться как нажатия клавиш.

Есть аналогичный вопрос о click событиях, которые также могут представлять интерес:

В jQuery, как я могу сказать между программным кликом и кликом пользователя?

Как вы заметили в комментариях, вы можете перехватывать click событий, чтобы обнаружить изменение фокуса на основе мыши и установить где-нибудь флаг, чтобы запомнить это. Тогда у вас будет это:

  1. Если в событии jQuery нет originalEvent, то изменение фокуса было инициировано вручную (т. е. $x.focus() или подобное).
  2. Если флаг обработчика щелчка установлен, то изменение фокуса произошло из-за действия мыши.
  3. В противном случае изменение фокуса произошло из-за события клавиатуры.

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

person mu is too short    schedule 17.07.2011
comment
Я могу использовать обработчик .click для обнаружения щелчков мышью, а затем обработчик .focus с этим originalEvent, чтобы различать события клавиатуры и триггера. Кажется, работает хорошо. Спасибо! - person mpen; 18.07.2011
comment
@Mark: Да, click, вероятно, лучше, чем пытаться обнаружить события клавиатуры. Тогда отсутствие originalEvent означает, что это было вызвано вручную, щелчок означает, что это было вызвано мышью, в противном случае это было с клавиатуры. Я добавлю это к своему ответу для дальнейшего использования. - person mu is too short; 18.07.2011
comment
В некоторых браузерах, по крайней мере в последних версиях Chrome, событие click происходит после события focus. Однако событие mousedown по-прежнему надежно происходит до focus, поэтому вы можете перехватить его, чтобы определить причину фокуса. - person DSimon; 26.03.2015
comment
@DSimon Но гарантируется ли заказ каким-либо стандартом? - person mu is too short; 26.03.2015
comment
@muistooshort Насколько я могу судить, к сожалению, нет. :-( - person DSimon; 27.03.2015
comment
Было бы справедливо отметить, что это решение jQuery. Я искал 'originalEvent', пытался найти его сам в объекте события, но в чистом JavaScript ничего подобного нет :/ - person Martin Melichar; 04.04.2020
comment
@MartinMelichar Вопрос помечен как jquery, и jQuery несколько раз упоминается в ответе. jQuery предоставляет собственную версию объекта события для (исторически) нормализации вещей в различных реализациях JavaScript. Не уверен, что есть решение на чистом JavaScript. - person mu is too short; 04.04.2020
comment
@muistooshort Я знаю, что для этого вопроса есть теги jQuery и JavaScript. Вот почему я опубликовал это. - person Martin Melichar; 04.04.2020
comment
Определенно не стоит использовать React, даже если вы полагаетесь на event.nativeEvent. - person Slbox; 09.03.2021