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

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

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

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

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

Ответ 1

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

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

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

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

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

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

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

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