使用jQuery / JavaScript进行关键组合

时间:2010-11-02 03:03:34

标签: javascript jquery plugins keyboard-shortcuts jkey

我很好奇我是如何使用以下jQuery插件代码在这个问题的底部写的,可以实现关键的组合。到目前为止它是如何工作的,它允许用户只需通过正常的jQuery语法创建键命令,并为键命令提供事件,如下所示:

$(window).jkey('a',function(){
   alert('you pressed the a key!');
});

$(window).jkey('b c d',function(){
   alert('you pressed either the b, c, or d key!');
});

最后我想要的是能力,但无法弄清楚:

$(window).jkey('alt+n',function(){
   alert('you pressed alt+n!');
});

我知道如何在插件外部执行此操作(在keyup上设置var false并在keydown上设置var true并检查当你按另一个键时var是否为真),但我不知道如何当你不知道要按哪些键以及多少键时,请执行此操作。如何添加此支持?我希望能够允许他们根据需要执行alt+shift+aa+s+d+f之类的操作。我无法理解如何实现这一点。有任何想法吗?

我将把它作为一个开源插件发布,我很乐意给予任何给予我权利,工作的人,在博客文章和代码中回答一些信用。提前谢谢!

(function($) {
  $.fn.jkey = function(keyCombo,callback) {
    if(keyCombo.indexOf(' ') > -1){ //If multiple keys are selected
        var keySplit = keyCombo.split(' ');
    }
    else{ //Else just store this single key
        var keySplit = [keyCombo];
    }
    for(x in keySplit){ //For each key in the array...

        if(keySplit[x].indexOf('+') > -1){
            //Key selection by user is a key combo... what now?
        }
        else{
            //Otherwise, it's just a normal, single key command
        }

        switch(keySplit[x]){
            case 'a':
                keySplit[x] = 65;
                break;
            case 'b':
                keySplit[x] = 66;
                break;
            case 'c':
                keySplit[x] = 67;
                break;
            //And so on for all the rest of the keys
        }
    }
    return this.each(function() {
        $this = $(this);
        $this.keydown(function(e){
            if($.inArray(e.keyCode, keySplit) > -1){ //If the key the user pressed is matched with any key the developer set a key code with...
                if(typeof callback == 'function'){ //and they provided a callback function
                    callback(); //trigger call back and...
                    e.preventDefault(); //cancel the normal
                }
            }
        });
    });
  }
})(jQuery);

4 个答案:

答案 0 :(得分:5)

使用keypress而不是keyup / keydown,因为后两者不能准确地保护密钥代码(reference,见最后一段)。在这种情况下,您可以引用事件对象的altKey ctrlKeyshiftKey布尔属性...

$(document).keypress(function(e) {
  var key = String.fromCharCode(e.which);
  var alt = e.altKey;
  var ctrl = e.ctrlKey
  var shift = e.shiftKey;
  alert("Key:" + key + "\nAlt:" + alt + "\nCtrl:" + ctrl + "\nShift:" + shift);
});

此外,您可以使用String.fromCharCode将密钥代码翻译为实际字母。

除了使用Ctrl,Alt和Shift组合之外,您不能捕获多个键。你根本无法在一个事件中做到这一点。所以把a+s+d+f的想法抛到窗外。

注意:显然浏览器使用某些键组合。例如,Alt + F通常会在Windows中显示“文件”菜单。 Ctrl + N通常会启动一个新窗口/选项卡。 尝试覆盖任何这些组合。

这是您live demo的测试乐趣。

答案 1 :(得分:2)

这就是我想出的。基本上我所做的是创建了一个存储所有密钥代码的JSON对象。然后我用代码替换所有提供的密钥。如果密钥使用'+'来创建密钥组合,那么我就会创建一个代码数组。

然后我们创建另一个数组来存储所有正在按下的键(keyDown添加项,keyUp将其删除)。在keyDown上,我们检查它是单键命令还是组合键。如果它是一个组合,我们会检查所有当前活动的按键。如果它们都匹配,我们执行回调。

这适用于任意数量的关键组合。只有当我使用'alert()'在键组合上显示消息时才会看到它不起作用,因为它将不再从活动的按键阵列中删除项目。

(function($) { 
  $.fn.jkey = function(keyCombo,callback) {

    // Save the key codes to JSON object
    var keyCodes = { 
      'a'   : 65,
      'b'   : 66,
      'c'   : 67,
      'alt' : 18
    };

    var x = '';
    var y = '';

    if(keyCombo.indexOf(' ') > -1){ //If multiple keys are selected
        var keySplit = keyCombo.split(' ');
    }
    else{ //Else just store this single key
        var keySplit = [keyCombo];
    }

    for(x in keySplit){ //For each key in the array...

      if(keySplit[x].indexOf('+') > -1){
        //Key selection by user is a key combo
        // Create a combo array and split the key combo
        var combo = Array();
        var comboSplit = keySplit[x].split('+');

        // Save the key codes for each element in the key combo
        for(y in comboSplit){
          combo[y] = keyCodes[ comboSplit[y] ];
        }

        keySplit[x] = combo;

      } else {
        //Otherwise, it's just a normal, single key command
        keySplit[x] = keyCodes[ keySplit[x] ];
      }

    }

    return this.each(function() {
        $this = $(this);

        // Create active keys array
        // This array will store all the keys that are currently being pressed
        var activeKeys = Array();

        $this.keydown(function(e){

          // Save the current key press
          activeKeys[ e.keyCode ] = e.keyCode;

          if($.inArray(e.keyCode, keySplit) > -1){ // If the key the user pressed is matched with any key the developer set a key code with...

            if(typeof callback == 'function'){ //and they provided a callback function
              callback(); //trigger call back and...
              e.preventDefault(); //cancel the normal
            }

          } else { // Else, the key did  not match which means it's either a key combo or just dosn't exist

            // Check if the individual items in the key combo match what was pressed
            for(x in keySplit){
              if($.inArray(e.keyCode, keySplit[x]) > -1){

                // Initiate the active variable
                var active = 'unchecked';

                // All the individual keys in the combo with the keys that are currently being pressed
                for(y in keySplit[x]) {
                  if(active != false) {
                    if($.inArray(keySplit[x][y], activeKeys) > -1){
                      active = true;
                    } else {
                      active = false;
                    }
                  }
                }

                // If all the keys in the combo are being pressed, active will equal true
                if(active === true){
                  if(typeof callback == 'function'){ //and they provided a callback function
                    callback(); //trigger call back and...
                    e.preventDefault(); //cancel the normal
                  }
                }
              }
            }

          } // end of if in array

        }).keyup(function(e) {
          // Remove the current key press
          activeKeys[ e.keyCode ] = '';
        });

    });

  }
})(jQuery);

答案 2 :(得分:0)

这只是在黑暗中拍摄的,但也许它会帮助你走正确的道路。

如果可以让该函数识别您输入的键的十六进制值而不是文字键(例如字母'n'的0x6E),则可以导出“alt + n”转换为十六进制的内容并让函数注意该值。

答案 3 :(得分:-1)

如果您正在寻找能够让用户轻松输入并使用普通输入框定义关键组合的内容,我编写了一个可以为您完成此操作的插件:http://suan.github.com/jquery-keycombinator/