hot-keys

Перехват клавиатурных комбинаций

by denvdmj

HTML

<!doctype html>
<html>
<head>
    <title>Перехват клавиатурных комбинаций</title>
    <meta http-equiv="content-type" content="text/html; charset=windows-1251"/>
    <script type="text/javascript">

    function print() {
        document.getElementById('EventDisplay').innerHTML = [].join.call(arguments,'<br>');
    };

    function upadateInfo () {
        document.getElementById('HotKeysDisplay').innerHTML = 'Горячие клавиши:<br />' + HotKeyManager.getAllHotKeys().join(', ')
    };

    function debugPrint(event, key) {
        print(
            'debugPrint',
            'нажата клавиша: ' + key,
            'event.type: ' + event.type,
            'keyCode: ' + event.keyCode,
            'charCode: ' + event.charCode,
            'время: ' + (+new Date)
        );
    };

    function CommonEH (event, hotKeyComb, ctrl, alt, shift) {
        print(
            'CommonEH',
            'Нажата горячая комбинация клавиш: ' + hotKeyComb,
            'keyCode: ' + event.keyCode,
            'charCode: ' + event.charCode,
            'время: ' + (+new Date)
        );
    };

    function CommonEH_2 (event, hotKeyComb, ctrl, alt, shift) {
        print(
            'CommonEH_2',
            'Нажата горячая комбинация клавиш: ' + hotKeyComb,
            'keyCode: ' + event.keyCode,
            'charCode: ' + event.charCode,
            'время: ' + (+new Date)
        );
    };

    addEH(window, 'load', function (event) {

        HotKeyManager.setOnHandle(debugPrint);
        HotKeyManager.setOnChange(upadateInfo);

        HotKeyManager.add({
            'F1, F2': CommonEH,
            'CTRL+A, CTRL+B, CTRL+C, CTRL+D, CTRL+E, CTRL+F, CTRL+G, CTRL+H, CTRL+I, CTRL+J, CTRL+K, CTRL+L, CTRL+M': CommonEH,
            'CTRL+N, CTRL+O, CTRL+P, CTRL+Q, CTRL+R, CTRL+S, CTRL+T, CTRL+U, CTRL+V, CTRL+W, CTRL+X, CTRL+Y, CTRL+Z': CommonEH,
            'F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12': CommonEH,
            'ESC, TAB, LEFT, UP, RIGHT, DOWN': CommonEH,
          ...

CSS

* {
  cursor: default;
}

html {
  font: 13px/140% "Verdana", sans-serif;
}

body {
  font: 13px/140% "Verdana", sans-serif;
  padding: 4em;
  margin: 0px;
  background: #EEE;
  text-align: left;
}

pre {
  clear: both;
}

h1, h2, h3, h4, h5, h6 {
  clear: both;  
}

#idDebugLog {
  clear: both;
  white-space: pre;
}

#HotKeysDisplay, 
#EventDisplay {
  float: left;
  font: 100%/150% "Consolas", monospace;
  border: 1px solid #FFF;
  border-radius: 6px;
  box-shadow:  
    #888 0px 0px 2px 0px, 
    #fff 0px 0px 2px 0px inset;
  
  width: 400px;
  height: 200px;
  padding: 1em;
  margin: 1em 1em 1em 0;
  
  background: #DDD;
  background: -webkit-gradient(linear, left top, left bottom, from(#DDD), to(#EEE));
  background: -moz-linear-gradient(left top, #DDD, #EEE);
  background: -o-linear-gradient(top,  #DDD, #EEE);
}

input[type="button"] {
  -o-transform-origin: 40px 16px;
  background-color: #E0E0E0;
  background: -webkit-gradient(linear, left top, left bottom, from(#FFFFFF), to(#E0E0E0));
  background: -moz-linear-gradient(top, #FFFFFF 0px, #E0E0E0 100%);
  background: -o-linear-gradient(top, #FFFFFF 0px, #E0E0E0 100%);
  border-radius: 6px;
  border: 1px solid #CCCCCC;
  border-bottom: 1px solid #AAAAAA;
  box-shadow:  
    #AAA 0px 0px 2px 0px, 
    #FFF 0px 0px 10px 0px inset;
  box-sizing: border-box;
  color: #555555;
  cursor: default;
  display: inline-block;
  font: normal normal 700 11px/150% "Arial";
  height: 32px;
  margin: 0px 2px 0px 0px;
  padding: 1px 10px;
  text-align: center;
  text-shadow: 0px 1px 0px #FFFFFF;
  vertical-align: middle;
  white-space: nowrap;
  word-wrap: normal;
}

input[type="button"]:hover {
  border-color: #aaa;
}

input[type="button"]:focus {
  outline: none;
  border-color: #4B95F1;
  box-shadow: #4B95F1 0px 0px 3px 0px, 
    #FFFFFF 0px 0px 10px 0px inset;
}

input[type="button"]::-moz-focus-inner {
  border: none;
  outline: none;
}

input[type="button"]:active:hover {
  border-color: #AAA;
  border-bottom-color:...

JavaScript

/*
    Фиксы.
    Изменил инициализацию indent, не было значения по умолчанию.
    Проверка циклических ссылок дополена проверкой на null, в msie часто вместо "null" выводилось "#CR#"
    Изменен вывод "свернутых" (при ограничении глубины рекурсии) объектов (и массивов), на такой: "[folded object: [object]]",
    некоторые нативные объекты нестандартно приводятся к строке, например (""+event.srcElement) --> "http://url/to/page.html",
    теперь это выглядит так: "[folded object: http://url/to/page.html]"
*/

(function(arr, str) {

    arr.indexOf || (arr.indexOf = function(v, start) {
        for (var i = start < 0 ? this.length + start : start || 0, l = this.length; i < l; i++)
        if (v === this[i]) return i;
        return -1
    });

    str.x = function(n) {
        // Подсмотрено у WingedFox'а, спасибо ему за это :-)
        return Array(n > 0 ? n + 1 : 0).join(this)
    };

    str.toHTML = function() {
        _pre.innerHTML = '*';
        _pre.firstChild.nodeValue = this;
        return _pre.innerHTML
    };

    var _pre = document.createElement('pre'),
        _crlf = '\r\n'.toHTML().length > 1 ? '\n' : '\r';

/*

Syntax:

    dump( <dumped object>, [<detect circular references>, [<indent or indent size>, [<escape html>, [<max depth>]]]] )

    <detect circular references>    -- зашита от циклических ссылок
    <indent or indent size>         -- строка или размер отступа
    <escape html>                   -- эскейпить недопустимые в html символы
    <max depth>                     -- максимальная глубина рекурсии (полезно при дампе, например, объекта event)

*/

    window.DUMP_JS = window.dump = function(value, detCR, indent, htmlescape, maxDepth) {

        indent = typeof indent == 'number' ? ' '.x(indent || 4) : indent || ' '.x(4);

        var
        register = [],
            errorValue = '[literalize error]',
            esc = {
                '\b': 'b',
                '\f': 'f',
                '\n': 'n',
                '\r': 'r',
    ...