我有以下代码
(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","down",function () {alert("Shouryuuken");});
它将所有组合存储在元素的数据上.当一系列键匹配时(由用户按下的所有键检查,而不是将该字符串的结尾与设置给元素的序列进行比较),我检查一个存储所有序列和回调函数的数组,看看是否有一个更加具体.如果它发现不会调用回调函数.
意思是,如果我按▼►▼►A它会触发Shouryuuken而不是Hadouken.
我想知道它是否可以更快,一直检查数组,看看是否有一些更具体的序列似乎很昂贵.
更新代码
最佳答案
您可以将组合存储在树数据结构中.一个关键的组合只是通过树的潜在“路径”.然后检查组合只意味着尝试遍历树的路径:
▼
|
►
/\
/ \
a ▼
| |
"Hadouken" ►
|
a
|
"Shouryuuken"