0

我希望发生的是,当用户单击输入字段时,他们会收到一个帮助文本,该文本将出现在 for 顶部,告诉他们要填写什么。目前它卡在一条消息上。

我的 HTML

<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();

我会非常感谢帮助。

这是一个小提琴,可以帮助您查看结果

4

1 回答 1

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);
}

问题是itemonfocus处理程序中指向itemas 是在for循环内定义的。在循环的每次迭代中for, 的内存位置item都会更新为新值,因此最后,每个onfocus处理程序都指向同一个item. 你必须强制一个新的范围,你可以通过使用立即调用的函数表达式来做到这一点。这有效地定义了一个新函数并立即调用它,从而创建了一个新范围。因此,对于循环item的每次迭代,您在函数内部都有一个新的for,这应该使您的onfocus处理程序的行为符合您的预期。

看看小提琴

正如评论中提到的numbers1311407,您也可以使用forEach代替for循环:

helpText.forEach(function (item) {
    document.getElementById(item.id).onfocus = function() {
       return showHelp(item.help);
       //showHelp(item.help);
   };        
});

这与使用 IIFE 的行为相同,但看起来没有那么尴尬。forEach所有浏览器都支持,但 IE 8 及以下不支持。

于 2013-10-29T17:09:54.043 回答