Быстрый фон:
- при нажатии клавиши в браузере генерируются три события: keyDown, keyPress и keyUp.
- keyDown и keyUp имеют свойство keyCode, которое примерно соответствует физической нажатой клавише.
- keyPress также имеет набор свойств charCode, который учитывает клавиши-модификаторы и раскладку клавиатуры (A и a имеют одинаковый keyCode, но разные charCode).
- все три события имеют свойства, указывающие, какие клавиши-модификаторы были нажаты во время этих событий.
Я главный разработчик noVNC, и у меня сложная проблема: noVNC нужен переведенный charCode без использования события keyPress по следующим причинам:
- noVNC необходимо отправлять события keyDown и keyUp отдельно на сервер VNC (иначе это не полностью функциональный клиент VNC).
- что еще более важно, noVNC должен предотвращать действия клавиатуры по умолчанию при подключении, что означает вызов метода preventDefault() события keyDown. Побочным эффектом этого является также предотвращение срабатывания события keyPress.
Из-за различий в раскладках клавиатуры (т. е. разных сопоставлений keyCode и charCode) я решил, что noVNC потребуется таблица поиска для разных раскладок клавиатуры.
Но вот настоящая проблема: в альтернативных макетах некоторые разные физические клавиши имеют ОДИНАКОВЫЙ keyCode. Например, при azerty (французской) раскладке клавиатуры клавиши "-" (тире) и "_" подчеркивания генерируют keyCode 189. Ack!!!
Итак... как мне получить правильное сопоставление keyCode с charCode и одновременно предотвратить действия браузера по умолчанию?
Кстати, я подозреваю, что это решение будет применимо к другим интерактивным веб-приложениям и играм HTML5, поскольку вы часто хотите знать полную информацию о нажатой клавише, не вызывая какой-либо дополнительный ответ браузера на это нажатие.
Полезные ссылки:
Решение: см. мой пост ниже.
Ответ 1 · рейтинг 9 · kanaka
Я решил свой вопрос. Это не 100% решение, но оно должно охватывать большую часть того, что необходимо. Надеемся, что когда поставщики браузеров начнут интегрировать DOM Level 3 Events, появится более чистое решение. а>.
Просто чтобы повторить основные ограничения:
- События нажатия клавиши и нажатия клавиши должны сообщаться/отправляться в то время, когда они действительно происходят. т.е. одновременной отправки клавиши вниз и клавиши во время события keyPress недостаточно.
- Многие комбинации клавиш должны быть полностью обработаны во время события keyDown либо потому, что они никогда не вызывают событие keyPress (например, клавиша Ctrl), либо потому, что действие по умолчанию должно быть остановлено в keyDown (WebKit), что предотвращает возникновение события keyPress.
- События key down и key должны сообщать о переведенном коде символа, а не о значении keyCode.
Без какого-либо нестандартного прозрения текущие реализации браузера, по-видимому, не позволяют полностью выполнить все три ограничения. Поэтому я решил немного ослабить ограничение №3.
В событии браузера keyDown добавьте событие в список нажатия клавиш и проверьте, является ли это безопасной комбинацией клавиш (отсутствие нежелательного поведения браузера по умолчанию):
Безопасно: ничего не делайте, пока не нажмете клавишу.
Небезопасно: немедленно сообщить/отправить событие нажатия клавиши. Здесь ограничение № 3 ослабляется, потому что эти ограниченные комбинации клавиш не преобразуются в код символа (во всяком случае, у многих из них их нет).
В браузерном событии keyPress (которое происходит сразу после события keyDown) проверьте, является ли это безопасной комбинацией клавиш:
Безопасно: сообщить/отправить событие нажатия клавиши. Обновите список нажатий клавиш, используя переведенный код символа (event.what).
Небезопасно: ничего не делать, так как об этом уже было сообщено/отправлено во время keyDown.
В событии браузера keyUp найдите и удалите соответствующее событие из списка нажатия клавиши и используйте переведенный код, чтобы сообщить/отправить событие нажатия клавиши.
Дополнительные ссылки для интересующихся:
Ответ 2 · рейтинг 3 · Tim Down
Это абсолютное минное поле, и я призываю вас не пытаться сделать это, если вы можете этого избежать. Существует не только длинная и запутанная история производителей браузеров, не согласных с ключевым поведением событий, но и тот факт, что они до сих пор не согласны и все еще регулярно меняют ключевое поведение своих браузеров.
Лучшее, что я могу предложить, и исчерпывающий ресурс по ключевым событиям браузера: http://unixpapa.com/js/key.html
Если вам придется это сделать, я думаю, вы получите множество таблиц сопоставления кодов ключей, которые очень быстро устареют. Удачи.