我正在尝试使用规则对象添加事件侦听器,例如
keyMap = [
{name: "Up", type: "keydown", code: 87, action: function(){alert("up")}},
{name: "Down", type: "keydown", code: 83, action: function(){alert("down")}},
{name: "Left", type: "keydown", code: 65, action: function(){alert("left")}},
{name: "Right", type: "keydown", code: 68, action: function(){alert("right")}}
]
for(var keyAct of keyMap){
if( typeof keyAct.action === "function" ){
document.addEventListener(keyAct.type, function(e){
if(e.keyCode === keyAct.code){
keyAct.action(e);
}
});
}
}
然后w / a / s / d按下所有警告“右”。我重写了for
这样的部分:
for(var keyAct of keyMap){
(function(keyAct){
if( typeof keyAct.action === "function" ){
document.addEventListener(keyAct.type, function(e){
if(e.keyCode === keyAct.code){
keyAct.action(e);
}
});
}
})(keyAct);
}
它有效,但这是唯一的方法吗?我能更优雅地做到吗?我的意思是,这看起来很奇怪。
答案 0 :(得分:1)
创建另一个绑定事件的函数,试试这个:
for(var i = 0, len = keyMap.length; i < len; ++i) {
if( typeof keyMap[i].action === "function" ) {
binder(keyMap[i]);
}
}
function binder(keyAct) {
document.addEventListener(keyAct.type, function(e) {
if(e.keyCode === keyAct.code) {
keyAct.action(e);
}
});
}
答案 1 :(得分:0)
我总是将这样的构建器函数分开,以避免不必要地重新构建构建器函数并且为了清晰起见:
for(var keyAct of keyMap){
if( typeof keyAct.action === "function" ){
document.addEventListener(keyAct.type, buildHandler(keyAct));
}
}
// Elsewhere
function buildHandler(keyAct){
return function(e) {
if(e.keyCode === keyAct.code){
keyAct.action(e);
}
};
}
旁注:for-in
循环不是为循环数组条目而设计的,它们用于循环遍历对象的可枚举属性。在数组上使用它们往往会让你遇到麻烦(如果你曾经直接或通过扩展Array.prototype
向数组中添加了可枚举的非索引属性)。详情:Myths and realities of for..in