代码之家  ›  专栏  ›  技术社区  ›  BrunoLM

如何优化此代码?

  •  5
  • BrunoLM  · 技术社区  · 14 年前

    我有以下代码

    (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 .

    我想知道它是否可以更快,一直检查数组,看看是否有一些更具体的序列似乎是昂贵的。

    更新代码

    1 回复  |  直到 14 年前
        1
  •  4
  •   Gabe Moothart    14 年前

    您可以将组合存储在树数据结构中。一个关键的组合将只是一个潜在的“路径”通过树。然后检查组合就意味着要尝试穿过树的路径:

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