2010-11-02 66 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