JavaScript. Подробное руководство, 6-е издание, стр. 272

<b>* 2) идентификатор нажатой клавиши</b>

<b>* Значение, возвращаемое функцией, становится возвращаемым значением</b>

<b>* обработчика события keydown. Если функция-обработчик вернет false,</b>

<b>* объект Keymap прервет всплытие события и предотвратит выполнение любых</b>

<b>* действий по умолчанию, связанных с событием keydown.</b>

<b>*</b>

<b>* Ограничения</b>

<b>*</b>

<b>* Функцию-обработчик можно привязать не ко всем клавишам. Некоторые комбинации</b>

<b>* используются самой операционной системой (например, Alt-F4). А некоторые комбинации</b>

<b>* могут перехватываться броузером (например, Ctrl-S). Эта реализация зависит</b>

<b>* от особенностей броузера, ОС и региональных настроек. Вы с успехом можете</b>

<b>* использовать функциональные клавиши и функциональные клавиши с модификаторами,</b>

<b>* а также алфавитно-цифровые клавиши без модификаторов. Комбинации алфавитно-цифровых</b>

<b>* клавиш с модификаторами Ctrl и Alt менее надежны.</b>

<b>*</b>

<b>* Поддерживается большинство знаков препинания, кроме дефиса, для ввода которых</b>

<b>* не требуется удерживать клавишу Shift ('=[];',./\) на клавиатурах</b>

<b>* со стандартной раскладкой US. Но они плохо совместимы с другими</b>

<b>* раскладками клавиатур, и их желательно не использовать.</b>

<b>*/</b>

<b>// Функция-конструктор </b>

<b>function Keymap(bindings) {</b>

<b>  this.map = {}; // Определить отображение идентификатор-&gt;обработчик</b>

<b>  if (bindings) { // Скопировать в него начальную карту привязок</b>

<b>    for(name in bindings) this.bind(name, bindings[name]);</b>

<b>  }</b>

<b>}</b>

<b>// Связывает указанный идентификатор клавиши с указанной функцией-обработчиком </b>

<b>Keymap.prototype.bind = function(key, func) {</b>

<b>  this.map[Keymap.normalize(key)] = func;</b>

<b>};</b>

<b>// Удаляет привязку для указанного идентификатора клавиши </b>

<div class="fb2-code"><code>&lt;b&gt;Keymap&lt;/b&gt;</code></div><b>.prototype.unbind = function(key) {</b>

<b>  delete this.map[Keymap.normalize(key)];</b>

<b>};</b>

<b>// Устанавливает этот объект Keymap в указанный HTML-элемент</b>

<b>Keymap.prototype.install = function(element) {</b>

<b>  var </b><div class="fb2-code"><code>&lt;b&gt;keymap&lt;/b&gt;</code></div><b> = this;</b>

<b>  // Определить функции-обработчика события</b>

<b>  function handler(event) { return keymap.dispatch(event, element); }</b>

<b>  // Установить ее</b>

<b>  if (element.addEventListener)</b>

<b>    element.addEventListener(&quot;keydown&quot;, handler, false);</b>

<b>  else</b>

<b>    if (element.attachEvent)</b>

<b>      element.attachEvent(&quot;onkeydown&quot;, handler);</b>

<b>};</b>

<b>// Этот метод делегирует обработку события клавиатуры, опираясь на привязки.</b>

<b>Keymap.prototype.dispatch = function(event, element) {</b>

<b>  // Изначально нет ни имен клавиш-модификаторов, ни имени клавиши</b>

<b>  var modifiers = &quot;&quot;</b>

<b>  var keyname = null;</b>

<b>  // Сконструировать строки модификаторов в каноническом виде из символов</b>

<b>  // в нижнем регистре, расположив их в алфавитном порядке.</b>

<b>  if (event.altKey) modifiers += &quot;alt_”;</b>

<b>  if (event.ctrlKey) modifiers += &quot;Ctrl,&quot;;</b>

<b>  if (event.metaKey) modifiers += &quot;meta_&quot;;</b>

<b>  if (event.shiftKey) modifiers += &quot;shift.”;</b>

<b>  // Имя клавиши легко получить, если реализовано свойство key,</b>

<b>  // определяемое стандартом DOM Level 3:</b>

<b>  if (event.key) keyname = event.key;</b>

<b>  // Для получения имен функциональных клавиш в Safari и Chrome можно</b>

<b>  // использовать свойство keyldentifier</b>

<b>  else </b>

<b>    if (event. keyldentifier&amp;&amp;event. keyldentifier. substrings, 2) !== &quot;U+&quot;)</b>