Как отправить необработанные нажатия клавиш в определенное поле ввода? - PullRequest
3 голосов
/ 27 марта 2012

Я пытаюсь сделать следующее, казалось бы, простое.

Если нажата клавиша, которая набрала бы символ в поле ввода текста, и нажатие этой клавиши еще не было обработано в другом месте (например, ни у какого поля ввода не было фокуса), тогда сфокусируйте одно конкретное поле ввода и введите персонаж там .

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

Предостережения:

  • Если какое-либо поле ввода имеет фокус, событие должно идти туда и больше никуда.
  • Клавиши, которые не печатают символы (Enter, клавиши со стрелками, PgUp, PgDn, ...), следует оставить для их поведения по умолчанию.

Используя jQuery, я придумал что-то вроде этого:

$(document).keypress(function(e) {
  var input = $("#my-input-field");
  if (e.which >= ' ' && !input.is(":focus")) {
    input.focus();
    input.trigger(e);
    e.preventDefault();
  }
});

Однако это не работает по двум причинам:

  1. События по-прежнему всплывают до document, даже если определенное поле ввода обрабатывает их. Возможные решения:
    • Подключите keypress обработчики событий ко всем полям ввода и вызовите stopPropagation в каждом, но это звучит как ужасный хак, ожидающий ошибки.
    • Проверьте в вышеупомянутом обработчике, имеет ли поле ввода текущий фокус, и проигнорируйте его, если это так, но это звучит так, как будто бы мне не хватало некоторых угловых случаев, когда что-то еще использует нажатия клавиш.
  2. Звонок .trigger(e) не работает. Он вызывает мои собственные обработчики событий, но не запускает поведение по умолчанию keypress при вставке символа.

Какой самый чистый выход?

Ответы [ 2 ]

6 голосов
/ 28 марта 2012

Думая об этом, события начинаются в следующем порядке: keydown, keyup, keypress.

. Вы можете использовать что-то вроде:

$(document.body).on('keydown', function(e) {
    if(document.activeElement.tagName.toLowerCase() != 'input') {
        $('#my-default-input').focus();
    }
});

Затем нажмите клавишусобытие завершится, позже оно запустит событие keyup (в теперь сфокусированном поле) и должно записать символ в поле, а затем запустит событие нажатия клавиши, которое могут использовать другие события (если таковые имеются), связанные с полем.

Содержимое оператора if можно изменить, чтобы отфильтровать определенные нажатия клавиш или добавить другие теги, например <canvas>, в список «не прикасаться».

Также обратите внимание, чтоЯ не проверял это, но теоретически это должно работать.:)

1 голос
/ 28 марта 2012

Вы не можете вручную запустить нажатие клавиши для пользователя (потенциальное нарушение безопасности), все, что trigger() делает в этом случае, - запускает любые прослушиватели событий, назначенные событию нажатия клавиши. Вы можете изменить значение текстового поля, используя .val (). Просто добавьте к нему персонажа.

Вы можете проверить, было ли нажатие клавиши выполнено в текстовом поле с if($(e.target).is('input')) в приемнике нажатия клавиши документа. Вы также можете добавить чек 'textarea', если хотите.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...