2010-09-07 21 views
5

Ho il seguente codice diCome posso ottimizzare questo codice?

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

Memorizza tutte le combinazioni sui dati dell'elemento. Quando una sequenza di chiavi corrisponde (è controllata da tutti i tasti premuti dall'utente che ha confrontato la fine di questa stringa con la sequenza impostata sull'elemento), controllo un array che memorizza tutte le sequenze e le funzioni di callback per vedere se ce n'è una più specifico. Se rileva che la funzione di callback non verrà chiamata.

Significato, se premo Un si innescherà Shouryuuken e non Hadouken.

Mi chiedo se può essere più veloce, controllando l'array tutto il tempo per vedere se ci sono sequenze più specifiche che sembrano costose.

codice di aggiornamento

+4

+10 se potessi per "Hadouken" !!! : D – karim79

risposta

4

Si potrebbe memorizzare le combo in una struttura dati ad albero. Una combinazione chiave sarebbe solo un potenziale "percorso" attraverso l'albero. Quindi controllare una combinazione significherebbe solo provare ad attraversare quel sentiero dell'albero:

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

Esattamente quello che vorrei suggerire. Creare una classe che abbia una matrice associativa di oggetti di classe come variabile membro. – palswim

+0

Grazie mille! Anche quella via è più semplice. Ecco il codice aggiornato http://jsfiddle.net/vZ9g4/ – BrunoLM

Problemi correlati