使用charCodeAt()从KeyCode中检索字符

时间:2013-01-29 20:06:00

标签: javascript jquery automation keyboard-shortcuts keycode

我正在尝试编写一个Javascript / jQuery函数,它会自动将键盘快捷键绑定到我的网页。我想到的方法如下:

  1. 使用以“key - ”
  2. 开头的类遍历所有元素
  3. 对于这些元素中的每一个,从类中检索键组合,例如'key-ctrl-s'将返回 Ctrl + S
  4. 将这些特定键组合的事件绑定到文档
  5. 非常基本的算法,或者我认为...... 问题即将来临......

    例如,我可以输入以下内容:

    <a href="javascript:void(0)" class="some_other_class ctrl+s">Save</a>
    <a href="javascript:void(0)" class="ctrl+shift+s">Save As</a>
    

    以上代码将生成以下键盘快捷键: Ctrl + S Ctrl + Shift + < KBD>取值

    当按下这些键时,将为相关的html元素触发click事件......

    问题

    如上所述,这里的算法非常简单,但是,像往常一样,在尝试编写时会出现问题。

    我无法看到在自动绑定事件时我将如何知道要侦听的键码(e.which)。

    例如:

    使用上面的HTML和以下的jQuery,我们可以到目前为止(忽略像正则表达式这样的东西):

    function keyboardShortcuts(){
        // Loop through all elements with a class containing 'key-'
        $("[class*='key-']").each(function(){
            // Using a regular expression here, separate the class into individual keys
            // whilst ignoring other classes and the 'key-' prefix
            var keys = $(this).attr('class').match(/REGEX HERE/);
    
            // THIS IS WHERE THE CODE GETS A LITTLE MESSY
            // I AM VERY UNSURE ABOUT THE FOLLOWING
    
            // Define all special characters and set them to false
            var ctrl = false, alt = false, shift = false;
    
            // First test for special characters
            // Test for ctrl key
            if(keys.indexOf('ctrl')!=-1){
                ctrl = true;
                // Remove ctrl from the keys array
                keys.splice(keys.indexOf('ctrl'),1)
            }
            // Test for alt key
            if(keys.indexOf('alt')!=-1){
                alt = true;
                // Remove alt from the keys array
                keys.splice(keys.indexOf('alt'),1)
            }
            // Test for shift key
            if(keys.indexOf('shift')!=-1){
                shift = true;
                // Remove shift from the keys array
                keys.splice(keys.indexOf('shift'),1)
            }
    
            // Determine special characters to test for
            if(ctrl&&alt&&shift){
    
                // Bind the keypress event to the document
    
                $(document).keypress(function(e) {
                    if((e.ctrlKey||e.metaKey)&&e.altKey&&shiftKey) {
    
                        var continue = true;
    
                        // Test for other characters in keys array
                        for(var i=0;i<keys.length;i++){
    
                            // THIS IS WHAT I AM REALLY UNSURE ABOUT
                            if(keys.indexOf(charCodeAt(e.which))==-1){
                                // Correct key was not pressed so do not continue
                                continue = false;
                            }
                        }
    
                        if(continue){
                            e.preventDefault();
                            // Proceed to triggering the click event
                            // No more help needed from here...
                        }
                    }
                    return true;
                });
            }else if(ctrl&&alt){
    
            }else if(ctrl&&shift){
    
            }else if(shift&&alt){
    
            }else if(ctrl){
    
            }else if(alt){
    
            }else if(shift){
    
            }
        });
    }
    

    正如你从上面所看到的,代码很长,但我根本看不到另一种编写方式...除了可能有一些整齐的数组在这里和那里,但即便如此嵌套如果声明几乎是必要的不是吗?

    最后,我的问题

    排除代码非常不整洁且可能写得更好/更好的事实(如果您对此有意见请提供),我的实际问题是参考以下行:

    keys.indexOf(charCodeAt(e.which))==-1
    

    这是一种在所有浏览器中从字符代码中检索字符的可靠方法吗?如果没有,有没有更好的方法呢?

    任何对其余代码有任何意见的人,请发帖,都希望得到一些反馈。

1 个答案:

答案 0 :(得分:1)

当我开始这个时,我并不打算改写整个事情。但我做了,你可以看到它在this jsfiddle工作。

该技术是查找所有目标元素并构建每个映射到哪些键组合的列表。我们将这些存储在数组keybindings中,每当有人按下某个键时,我们会查看整个列表以查找匹配项。如果我们找到一个,我们会在元素上触发click事件。

我使用keydown代替keypress,因为您实际上已经获得了修饰符信息。我还改进了类字符串解析,但我可以肯定它可以做得更清洁。

这是JS代码。

var keybindings = [];

$('[class*="key-"]').each(function (idx, val) {
    var keyspec = {
        which: 0,
        altKey: false,
        shiftKey: false,
        ctrlKey: false,
        element: val
    };

    var keystring = $(val).attr('class').toLowerCase();
    var match = /key-\S+/.exec(keystring);
    var parts = match.toString().split('-');
    keyspec.which = parts[ parts.length-1 ].toUpperCase().charCodeAt(0);
    for (var jdx in parts) {
        if (parts[jdx] == 'alt') keyspec.altKey = true;
        else if (parts[jdx] == 'shift') keyspec.shiftKey = true;
        else if (parts[jdx] == 'ctrl') keyspec.ctrlKey = true;
    }
    keybindings.push( keyspec );
});

$(document).keydown( function(evt) {
    $.each(keybindings, function(idx, oneBind) {
       if (evt.which == oneBind.which
           && evt.altKey == oneBind.altKey
           && evt.shiftKey == oneBind.shiftKey
           && evt.ctrlKey == oneBind.ctrlKey)
           $(oneBind.element).click();
    });
});

当然,现在我发现可能有一个jquery插件,我们可以使用它。