我想要发生的是,当用户点击输入领域时,他们会获得一个帮助文本,该文本将出现在for的顶部,告诉他们要填写什么。目前它被卡在一条消息上
<p id="help">Helpful notes will appear here</p>
<p>E-mail: <input type="text" id="email" name="email" /> </p>
<p>Name: <input type="text" id="name" name="name" /> </p>
<p>Age: <input type="text" id="age" name="age" /> </p>
function showHelp(help) {
document.getElementById('help').innerHTML = help;
}
function setupHelp() {
var helpText = [
{'id': 'email', 'help': 'Your e-mail address'},
{'id': 'name', 'help': 'Your full name'},
{'id': 'age', 'help': 'Your age (you must be over 16 to play game)'}
];
for (var i = 0; i < helpText.length; i++ ) {
var item = helpText[i];
document.getElementById(item.id).onfocus = function() {
return showHelp(item.help);
};
}
}
setupHelp();
我会非常乐意帮助。
答案 0 :(得分:3)
你被封闭的小虫咬了!
请改为:
for (var i = 0; i < helpText.length; i++ ) {
var item = helpText[i];
(function(item) {
document.getElementById(item.id).onfocus = function() {
return showHelp(item.help);
};
})(item);
}
问题是item
处理程序中的onfocus
指向item
循环中定义的for
。在for
循环的每次迭代期间,item
的内存位置都更新为新值,因此最后,每个onfocus
处理程序指向相同的item
。您必须强制使用新范围,并且可以使用立即调用的函数表达式来执行此操作。这有效地定义了一个新函数并立即调用它,从而创建了一个新的作用域。因此,对于item
循环的每次迭代,函数内部都有一个新的for
,这应该使您的onfocus
处理程序的行为符合您的预期。
查看fiddle。
评论中提及numbers1311407,您也可以使用forEach
代替for
循环:
helpText.forEach(function (item) {
document.getElementById(item.id).onfocus = function() {
return showHelp(item.help);
//showHelp(item.help);
};
});
这种行为方式相同,但看起来不如使用IIFE那么尴尬。所有浏览器都支持forEach
,但IE 8及以下版本不支持它。