2010-09-07 8 views
5

J'ai le code suivantComment puis-je optimiser ce code?

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

Il stocke toutes les combinaisons sur les données de l'élément. Quand une séquence de clés correspond (elle est vérifiée par toutes les touches pressées par l'utilisateur comparée à la fin de cette chaîne par rapport à la séquence définie sur l'élément), je vérifie un tableau qui stocke toutes les séquences et fonctions de rappel pour voir s'il y en a plus spécifique. S'il trouve la fonction de rappel ne sera pas appelée.

Signification, si je presse ▼ ►▼ ►A il déclenche Shouryuuken et non Hadouken.

Je me demande si cela peut être plus rapide, vérifier le tableau tout le temps pour voir s'il y a des séquences plus spécifiques qui me parait cher.

Code de mise à jour

+4

+10 si je pouvais pour 'Hadouken' !!! : D – karim79

Répondre

4

Vous pouvez stocker vos combos dans une structure de données d'arbre. Une combinaison de touches serait simplement un "chemin" potentiel à travers l'arbre. Puis vérifier une combinaison signifierait simplement essayer de traverser ce chemin de l'arbre:

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

Exactement ce que je suggère. Créez une classe qui a un tableau associatif d'objets de classe en tant que variable membre. – palswim

+0

Merci beaucoup! De cette façon est plus simple aussi. Voici le code mis à jour http://jsfiddle.net/vZ9g4/ – BrunoLM