2010-09-07 144 views
5

我有以下代碼如何優化此代碼?

(function($){ 
    $.fn.kb = function(evt, map, fn, options) 
    { 
     var _this = this; 
     var modifiers = [17, 18, 19]; 

     function precise(a, b) 
     { 
      return b.Size - a.Size; 
     } 

     if (!this.data("Combos")) 
      this.data("Combos", []); 

     var combos = this.data("Combos"); 
     var combo = { Size: map.Keys.length, Function: fn, Keys: map.Keys.join("").toLowerCase() }; 
     combos.push(combo) 
     combos.sort(precise); 

     map = $.extend({ Modifiers: [], Keys: [] }, map); 
     var KeysTimerKey = "KeysTimer" + map.Modifiers.join("") + map.Keys.join(""); 
     var KeysKeyKey = "Keys" + map.Modifiers.join("") + map.Keys.join(""); 

     options = $.extend({NoInput:false, Delay: 350, PreventDefault:false}, options); 

     var specialKeys = { 27: 'esc', 9: 'tab', 32:'space', 13: 'return', 8:'backspace', 145: 'scroll', 
      20: 'capslock', 144: 'numlock', 19:'pause', 45:'insert', 36:'home', 46:'del', 
      35:'end', 33: 'pageup', 34:'pagedown', 37:'left', 38:'up', 39:'right',40:'down', 
      109: '-', 
      112:'f1',113:'f2', 114:'f3', 115:'f4', 116:'f5', 117:'f6', 118:'f7', 119:'f8', 
      120:'f9', 121:'f10', 122:'f11', 123:'f12', 191: '/'}; 

     var FromCharCode = 
      function(code) 
      { 
       if (specialKeys[code] != undefined) 
        return specialKeys[code]; 

       return String.fromCharCode(code); 
      }; 

     this.bind 
     (
      evt, 
      function(e) 
      { 
       if (modifiers.indexOf(e.keyCode) == -1) 
       { 
        if (options.NoInput && ["input", "textarea"].indexOf(e.target.tagName.toLowerCase()) > -1) return; 

        var ctrl = map.Modifiers.join("$").match(/ctrl/i) != null; 
        var shift = map.Modifiers.join("$").match(/shift/i) != null; 
        var alt = map.Modifiers.join("$").match(/alt/i) != null; 

        if (e.ctrlKey == ctrl && 
         e.altKey == alt && 
         e.shiftKey == shift) 
        { 
         var key = FromCharCode(e.keyCode); 
         if (((e.ctrlKey || e.altKey || e.shiftKey) || specialKeys[e.keyCode] != undefined) && 
          options.PreventDefault) e.preventDefault(); 

         if (_this.data(KeysTimerKey) != null) clearTimeout(_this.data(KeysTimerKey)); 

         var keys = _this.data(KeysKeyKey) || []; 
         keys.push(FromCharCode(e.keyCode)); 
         _this.data(KeysKeyKey, keys); 

         _this.data(KeysTimerKey, setTimeout(function(){ _this.data(KeysKeyKey, ""); }, options.Delay)); 

         var input = _this.data(KeysKeyKey).join("").toLowerCase(); 
         var keys = map.Keys.join("").toLowerCase(); 

         if (input.slice(-keys.length) == keys) 
         { 
          var found = -1; 
          for (var i = 0; i < combos.length; ++i) 
          { 
           if (combos[i].Keys.slice(-keys.length) == input) 
           { 
            if (keys.length >= combos[i].Keys.length) found = i; 
           } 
          } 
         } 

         if (found >= 0) 
         { 
          combos[found].Function(e); 
          _this.data(KeysKeyKey, null); 
         } 
        } 
       } 
      } 
     ); 
    } 
})(jQuery); 


/**/ 
$(window).kb("keydown", { Modifiers: [], Keys: ["down", "right", "a"] }, function() {alert("Hadouken");}); 
$(window).kb("keydown", { Modifiers: [], Keys: ["down", "right", "down", "right", "a"] }, function() {alert("Shouryuuken");}); 

它存儲在元件中的數據的所有組合。當一系列鍵匹配時(通過用戶按下的所有鍵來檢查,而不是將該字符串的結尾與設置爲元素的序列進行比較),我檢查一個存儲所有序列和回調函數的數組,以查看是否存在一個更具體。如果它發現回調函數不會被調用。

意義,如果我按一個會觸發Shouryuuken而不是Hadouken

我不知道它是否可以更快,檢查陣列所有的時間,看看是否有一些更具體的序列看起來很昂貴。

更新代碼

+4

+10如果我可以爲'Hadouken'! :D – karim79 2010-09-07 20:53:17

回答

4

你可以存儲在一個樹數據結構中的連擊。一個關鍵組合只是通過樹的潛在「路徑」。然後檢查一個組合只會意味着試圖遍歷該樹的路徑:

 ▼ 
     | 
     ► 
     /\ 
    /\ 
     a ▼ 
     | | 
"Hadouken" ► 
      | 
      a 
      | 
     "Shouryuuken" 
+0

準確地說,我會建議。創建一個具有類對象的關聯數組作爲成員變量的類。 – palswim 2010-09-07 21:15:06

+0

非常感謝!這種方式也更簡單。這裏是更新的代碼http://jsfiddle.net/vZ9g4/ – BrunoLM 2010-09-08 00:04:45