如何优化这段代码?

5
我有以下代码
(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");});

它将所有组合存储在元素数据中。当按键序列匹配时(由用户按下的所有键进行检查,然后将其字符串末尾与设置为元素的序列进行比较),我会检查一个存储所有序列和回调函数的数组,以查看是否有更多特定的内容。如果找到回调函数,将不会调用它。
也就是说,如果我按下 A,它将触发 Shouryuuken 而不是 Hadouken
我想知道是否可以更快地进行操作,因为始终检查数组是否存在一些更具体的序列似乎很昂贵。
更新代码

4
+10分如果我能用“波动拳”!!! :D - karim79
1个回答

4

您可以使用树形数据结构存储组合键。一个键组合只是该树中潜在的“路径”。因此,检查组合键只需要尝试遍历该树的路径:

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

正是我建议的。创建一个类,其中具有关联数组(associative array)的类对象作为成员变量。 - palswim
非常感谢!那种方式也更简单。这是更新后的代码 http://jsfiddle.net/vZ9g4/ - BrunoLM

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接