2010-09-07 18 views
5

Ich habe den folgenden CodeWie kann ich diesen Code optimieren?

(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");}); 

Es speichert alle Kombinationen auf den Daten des Elements. Wenn eine Sequenz von Schlüsseln übereinstimmt (es wird durch alle vom Benutzer gedrückten Tasten geprüft, als das Ende dieses Strings mit der für das Element festgelegten Sequenz verglichen), überprüfe ich ein Array, das alle Sequenzen und Callback-Funktionen speichert, um zu sehen, ob es einen gibt spezifischer. Wenn es findet, wird die Callback-Funktion nicht aufgerufen.

Bedeutung, wenn ich A drücken, wird es Shouryuuken und nicht Hadouken auslösen.

Ich frage mich, ob es schneller sein kann, überprüfen Sie das Array die ganze Zeit, um zu sehen, ob es einige spezifischere Sequenzen scheint teuer.

Update-Code

+4

+10 wenn ich für 'Hadouken' könnte !!! : D – karim79

Antwort

4

Sie könnten Ihre Combos in einer Baumdatenstruktur speichern. Eine Tastenkombination wäre nur ein möglicher "Pfad" durch den Baum. Dann würde das Überprüfen einer Kombination nur bedeuten, dass versucht wird, diesen Pfad des Baums zu durchqueren:

+0

Genau das, was ich vorschlagen würde. Erstellen Sie eine Klasse mit einem assoziativen Array von Klassenobjekten als Membervariable. – palswim

+0

Vielen Dank! Dieser Weg ist auch einfacher. Hier ist der aktualisierte Code http://jsfiddle.net/vZ9g4/ – BrunoLM