2010-09-07 16 views
5

Mam następujący kodJak mogę zoptymalizować ten kod?

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

Przechowuje wszystkie kombinacje na danych elementu. Kiedy sekwencja klawiszy się zgadza (jest sprawdzana przez wszystkie klawisze wciśnięte przez użytkownika, niż porównywana końcówka tego ciągu do sekwencji ustawionej na element), sprawdzam tablicę, która przechowuje wszystkie sekwencje i funkcje zwrotne, aby sprawdzić, czy jest jeden bardziej szczegółowo. Jeśli stwierdzi, że funkcja zwrotna nie zostanie wywołana.

znaczenie, jeśli nacisnę A będzie wyzwalać Shouryuuken i nie Hadouken.

Zastanawiam się, czy to może być szybsze, sprawdzanie tablicy przez cały czas, aby zobaczyć, czy są jakieś bardziej szczegółowe sekwencje wydaje się drogie.

kod Aktualizacja

+4

+10 gdybym mógł dla "Hadouken" !!! : D – karim79

Odpowiedz

4

Można by przechowywać swoje combo w strukturze danych drzewo. Kombinacja klawiszy byłaby po prostu potencjalną "ścieżką" w drzewie. Wtedy sprawdzenie kombinacji oznaczałoby po prostu próbę przemierzania tej ścieżki drzewa:

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

Dokładnie to, co bym zasugerował. Utwórz klasę, która ma asocjacyjną tablicę obiektów klasy jako zmienną składową. – palswim

+0

Dziękuję bardzo! W ten sposób jest również łatwiej. Oto zaktualizowany kod http://jsfiddle.net/vZ9g4/ – BrunoLM

Powiązane problemy