2010-11-02 48 views
7

我很好奇我如何用下面的jQuery插件代码即时编写这个问题的底部,可以实现关键的组合。它是如何工作的,到目前为止是它允许用户只需通过做一个正常的jQuery像语法创建关键命令和键盘命令提供了一个事件,像这样:使用jQuery/JavaScript做关键组合

$(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虚假和的keydown设置VAR真实和检查如果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); 

回答

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); 
+0

您正在全局范围内定义'x'。 – 2010-11-04 23:42:41

+0

我认为范围问题可以通过像这样定义x和y来解决:var x =''; var y =''; ? – sebnitu 2010-11-05 01:13:31

+0

或者更好的是,我们可以通过在for语句中添加var来定义它们? for(var x in keySplit){... – sebnitu 2010-11-05 01:18:34

0

这只是一个黑暗中的镜头,但也许它会帮助你走向正确的道路。

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

+0

AWH,有趣的,生病了解更多。谢谢!另外,你有参考如何通过JS转换它们?我还没有谷歌搜索... – 2010-11-04 17:18:34

5

使用keypress而不是keyup/keydown,因为后两者不能精确地产生键码(reference,请参见最后一段)。您也可以参考事件对象的altKeyctrlKeyshiftKey布尔属性在这种情况下...

$(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组合外,您无法捕获多个键。你根本无法在单一事件中做到这一点。所以把想法抛出窗外。

注意:显然有一些浏览器使用的组合键。例如,Alt + F通常会打开Windows中的文件菜单。 Ctrl + N通常会启动一个新窗口/选项卡。如果不是试图覆盖任何这些组合。

这里有一个live demo为您的测试乐趣。

+0

那么,我如何整合,但我怎么整合它,以便任何组合将工作,例如shift + alt + f + d + s如果他们想要的话。就像我说的,这对我来说,但它也将公开发布,所以我仍然需要允许然后覆盖像ctrl + t浏览器的默认值,虽然我从来不会:) – 2010-11-04 17:35:57

+0

糟糕,那么,那么shift + alt + f,我如何将它集成到插件中,对不起 – 2010-11-04 17:39:02

+0

你不能捕获多个键,所以忘掉它。该活动每按一次键就会触发一次。布尔指标简单地告诉你当按下按键时是否按住Ctrl,Alt或Shift键。至于覆盖浏览器的默认值,不,NO和** NO!** – 2010-11-04 17:39:08