mozilla.orgで Javascript のクロージャについて勉強してい ます。完全に私を吹き飛ばしたよくある間違いと呼ばれるセクションがあります。本当に何を言っているのかわからない。
コードは次のとおりです。
<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)'}
];
for (var i = 0; i < helpText.length; i++) {
var item = helpText[i];
document.getElementById(item.id).onfocus = function() {
showHelp(item.help);
}
}
}
setupHelp();
テキストはヘルプに表示されます
最後のヘルプ「あなたの年齢(あなたは16歳以上でなければなりません)」のみを表示し、解決策はsetupHelpの外でshowHelp関数を書き直すことです
function makeHelpCallback(help) {
return function() {
showHelp(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)'}
];
for (var i = 0; i < helpText.length; i++) {
var item = helpText[i];
document.getElementById(item.id).onfocus = makeHelpCallback(item.help);
}
}
setupHelp();
問題が解決するメカニズムがわかりません。DOM へのアクセスに javascript を使用したことがなく、jQuery を使用したため、jQuery で関数を書き直しました。
function makeHelpCallback(i) {
return function () {
$("#help").text(i);
};
}
(function () {
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)' }
];
for (var i = 0; i < helpText.length; i++) {
var item = helpText[i];
$("#"+item.id).focus(function () {
new makeHelpCallback(item.help)();
});
}
})();
しかし、バグは消えません。私の知る限り、jQuery には onfocus ハンドラーがありません。ハンドラーを同じレベルのリスナーにバインドすることは不可能です。function(){} の下に移動する必要があります。そして、Javascript ができるのと同じ効果を達成することはできません。
とにかく、Javascript コードに相当するコードを書く方法はありますか?
説明によると、リスナーは同じ環境を共有しているため、機能しません。それが何を意味するにせよ、onfocus = function(){showHelp(item.help)} は 3 回別々に実行されました。それに応じてバインドする必要があります。なぜ彼らは同じようになるのでしょうか?showHelp は静的オブジェクトだからですか? もしそうなら、新しい修飾子を追加することでうまくいくはずです。また、makeHelpCallback(item.help) も同じ環境を共有します。しかし、それは機能します。なぜ、なぜ、なぜ???
テストの便宜のために、完全な HTML コードが添付されています。
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
</head>
<body>
<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>
<script src="Scripts/jquery-1.9.1.min.js"></script>
<script>
function makeHelpCallback(i) {
return function () {
$("#help").text(i);
};
}
(function () {
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)' }
];
for (var i = 0; i < helpText.length; i++) {
var item = helpText[i];
$("#" + item.id).focus(function () {
makeHelpCallback(item.help)();
});
}
})();
</script>
</body>
</html>