javascript - 你能给我看一些 Keymap.js(权威指南)的例子吗?

标签 javascript keymapping

function Keymap(bindings) {
    this.map = {};    // Define the key identifier->handler map
    if (bindings) {   // Copy initial bindings into it
        for(name in bindings) this.bind(name, bindings[name]);
    }
}

// Bind the specified key identifier to the specified handler function
Keymap.prototype.bind = function(key, func) {
    this.map[Keymap.normalize(key)] = func;
};

// Delete the binding for the specified key identifier
Keymap.prototype.unbind = function(key) {
    delete this.map[Keymap.normalize(key)];
};

// Install this Keymap on the specified HTML element
Keymap.prototype.install = function(element) {
    // This is the event-handler function
    var keymap = this;
    function handler(event) { return keymap.dispatch(event, element); }

    // Now install it
    if (element.addEventListener)
        element.addEventListener("keydown", handler, false);
    else if (element.attachEvent) 
        element.attachEvent("onkeydown", handler);
};

// This method dispatches key events based on the keymap bindings.
Keymap.prototype.dispatch = function(event, element) {
    // We start off with no modifiers and no key name
    var modifiers = ""
    var keyname = null;

    // Build the modifier string in canonical lowercase alphabetical order.
    if (event.altKey) modifiers += "alt_";      
    if (event.ctrlKey) modifiers += "ctrl_";
    if (event.metaKey) modifiers += "meta_";
    if (event.shiftKey) modifiers += "shift_";

    // The keyname is easy if the DOM Level 3 key property is implemented:
    if (event.key) keyname = event.key;
    // Use the keyIdentifier on Safari and Chrome for function key names
    else if (event.keyIdentifier && event.keyIdentifier.substring(0,2) !== "U+")
        keyname = event.keyIdentifier;
    // Otherwise, use the keyCode property and the code-to-name map below
    else keyname = Keymap.keyCodeToKeyName[event.keyCode];

    // If we couldn't figure out a key name, just return and ignore the event.
    if (!keyname) return;

    // The canonical key id is modifiers plus lowercase key name
    var keyid = modifiers + keyname.toLowerCase();

    // Now see if the key identifier is bound to anything
    var handler = this.map[keyid];

    if (handler) {  // If there is a handler for this key, handle it
        // Invoke the handler function
        var retval = handler.call(element, event, keyid);

        // If the handler returns false, cancel default and prevent bubbling
        if (retval === false) {
            if (event.stopPropagation) event.stopPropagation();  // DOM model
            else event.cancelBubble = true;                      // IE model
            if (event.preventDefault) event.preventDefault();    // DOM
            else event.returnValue = false;                      // IE
        }

        // Return whatever the handler returned
        return retval;
    }
};

// Utility function to convert a key identifier to canonical form.
// On non-Macintosh hardware, we could map "meta" to "ctrl" here, so that
// Meta-C would be "Command-C" on the Mac and "Ctrl-C" everywhere else.
Keymap.normalize = function(keyid) {
    keyid = keyid.toLowerCase();           // Everything lowercase
    var words = keyid.split(/\s+|[\-+_]/); // Split modifiers from name
    var keyname = words.pop();             // keyname is the last word
    keyname = Keymap.aliases[keyname] || keyname; // Is it an alias?
    words.sort();                          // Sort remaining modifiers
    words.push(keyname);                   // Add the normalized name back 
    return words.join("_");                // Concatenate them all
};

Keymap.aliases = {        // Map common key aliases to their "official" 
    "escape":"esc",       // key names used by DOM Level 3 and by 
    "delete":"del",       // the key code to key name map below.
    "return":"enter",     // Both keys and values must be lowercase here.
    "ctrl":"control",
    "space":"spacebar",
    "ins":"insert"
};

// The legacy keyCode property of the keydown event object is not standardized
// But the following values seem to work for most browsers and OSes.
Keymap.keyCodeToKeyName = {
    // Keys with words or arrows on them
    8:"Backspace", 9:"Tab", 13:"Enter", 16:"Shift", 17:"Control", 18:"Alt",
    19:"Pause", 20:"CapsLock", 27:"Esc", 32:"Spacebar", 33:"PageUp",  
    34:"PageDown", 35:"End", 36:"Home", 37:"Left", 38:"Up", 39:"Right",
    40:"Down", 45:"Insert", 46:"Del",

    // Number keys on main keyboard (not keypad)
    48:"0",49:"1",50:"2",51:"3",52:"4",53:"5",54:"6",55:"7",56:"8",57:"9",

    // Letter keys. Note that we don't distinguish upper and lower case
    65:"A", 66:"B", 67:"C", 68:"D", 69:"E", 70:"F", 71:"G", 72:"H", 73:"I",
    74:"J", 75:"K", 76:"L", 77:"M", 78:"N", 79:"O", 80:"P", 81:"Q", 82:"R",
    83:"S", 84:"T", 85:"U", 86:"V", 87:"W", 88:"X", 89:"Y", 90:"Z",

    // Keypad numbers and punctuation keys. (Opera does not support these.)
    96:"0",97:"1",98:"2",99:"3",100:"4",101:"5",102:"6",103:"7",104:"8",105:"9",
    106:"Multiply", 107:"Add", 109:"Subtract", 110:"Decimal", 111:"Divide",

    // Function keys
    112:"F1", 113:"F2", 114:"F3", 115:"F4", 116:"F5", 117:"F6",
    118:"F7", 119:"F8", 120:"F9", 121:"F10", 122:"F11", 123:"F12",
    124:"F13", 125:"F14", 126:"F15", 127:"F16", 128:"F17", 129:"F18",
    130:"F19", 131:"F20", 132:"F21", 133:"F22", 134:"F23", 135:"F24",

    // Punctuation keys that don't require holding down Shift
    // Hyphen is nonportable: FF returns same code as Subtract
    59:";", 61:"=", 186:";", 187:"=", // Firefox and Opera return 59,61 
    188:",", 190:".", 191:"/", 192:"`", 219:"[", 220:"\\", 221:"]", 222:"'"
};

JavaScript:权威指南:第 6 版 Keymap.js

Keymap.js:将按键事件绑定(bind)到处理函数。

该模块定义了一个Keymap类。该类的一个实例代表一个 键标识符(下面定义)到处理函数的映射。键盘映射 可以安装在 HTML 元素上来处理 keydown 事件。当这样一个 事件发生时,Keymap 使用其映射来调用适当的处理程序。

当你创建一个Keymap时,你可以传递一个JavaScript对象来表示 键盘映射的初始绑定(bind)集。该对象的属性名称 是关键标识符,属性值是处理函数。 创建 Keymap 后,您可以通过传递键来添加新的绑定(bind) 标识符和处理程序函数绑定(bind)()方法。您可以删除一个 通过将 key 标识符传递给 unbind() 方法进行绑定(bind)。

要使用键盘映射,请调用其 install() 方法,并传递 HTML 元素, 例如文档对象。 install() 添加一个 onkeydown 事件处理程序 指定的对象。当调用此处理程序时,它会确定 key 按下的键的标识符并调用处理函数(如果有), 绑定(bind)到该 key 标识符。单个键盘映射可以安装在多个 一个 HTML 元素。

关键标识符

key 标识符是 key 加号的不区分大小写的字符串表示形式 同时按住的任何修饰键。关键名称是 通常是按键上的(未移动的)文本。合法的键名称包括“A”、“7”、 “F2”、“PageUp”、“向左”、“退格”和“Esc”。

请参阅此模块中的 Keymap.keyCodeToKeyName 对象以获取名称列表。 这些是 DOM Level 3 标准定义的名称的子集 该类在实现时将使用事件对象的 key 属性。

键标识符还可以包括修饰键前缀。这些前缀是 Alt、Ctrl、Meta 和 Shift。它们不区分大小写,并且必须分开 从键名开始,并且彼此之间用空格或下划线连接, 连字符或+。例如:“SHIFT+A”、“Alt_F2”、“meta-v”和“ctrl alt left”。 在 Mac 上,Meta 是 Command 键,Alt 是 Option 键。一些浏览器 将 Windows 键映射到 Meta 修饰符。

处理函数

处理程序作为文档或文档元素的方法被调用 键映射已安装并​​传递两个参数: 1)keydown事件的事件对象 2) 按下的按键的按键标识符 处理程序返回值成为 keydown 处理程序的返回值。 如果处理函数返回 false,则键盘映射将停止冒泡并 取消与 keydown 事件关联的任何默认操作。

...

最佳答案

代码摘要:

  • KeyMap 的新实例是通过 new 关键字创建的。
    或者,可以传递包含键映射的对象来预先绑定(bind):

    {
      "key-combi1": func1,   //key-combi such as alt+a, ctrl+c, shift+s
      "key-combi2": func2,
      ....
      "key-combin": funcn    //<-- Last property should not end with a comma
    }
    
  • 创建新实例(var keymap = new Keymap();)后,可以使用以下方法(按逻辑时间顺序收听):

    1. bind - 添加额外的按键绑定(bind)
      keymap.bind( "key-combi", function );
    2. unbind - 删除按键绑定(bind)
      keymap.unbind( "key-combi");
    3. install - 将按键映射附加到元素(绑定(bind)到 keydown 事件)
      keymap.install( 元素 );

示例

使用此方法的最简单方法如下所示:

var keymap = new Keymap;                       // Create a new instance of Keymap
keymap.bind("ctrl_a", function(event, keyid) { // Bind key combi: ctrl+a
    alert("Key pressed down! KeyId: " + keyid)
});
keymap.install(document.body);                 // Attach keymap to <body>

另一种方法,具有相同的结果:

var keymap = new Keymap({                      // Create a new instance of Keymap
    "ctrl_a": function(event, keyid) {         // Bind key combi: ctrl+a
        alert("Key pressed down! KeyId: " + keyid)
    }
});
keymap.install(document.body);                 // Attach keymap to <body>

关于javascript - 你能给我看一些 Keymap.js(权威指南)的例子吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8768667/

相关文章:

javascript - 关闭其他子菜单

javascript - jQuery:仅当第一个(:第一个)TD 不包含文本(:empty)时,才为所有空的子 TD 设置样式

javascript - 如何根据下拉列表中的值和用户输入更新工资

visual-studio-2010 - 如何覆盖 Visual Studio 的菜单加速器快捷方式?

windows - 在注册表中为单个用户重新映射 key

android - 如何在 android 中使用 Dictionary(如 iphone NSDictionary)?

javascript - 高分提醒 - 下一行和标题

javascript - jquery animate 在 chrome 中不起作用

visual-studio-2010 - 在 PyCharm 中使用 Visual Studio 键盘映射。寻找PDF

vim - 如何在 Vim 中快速选择(内部)行