定義イベントリスナー(または他の非同期のもの)のようになります。 btnVal
いくつかの異なる変数を作成していると思うかもしれませんが、ループを通過するたびに1つずつですが、そうではありません。あなたのコードは次のように振る舞う終わるようbtnValが得ることVARは、トップに掲揚し、再利用:
var btnVal;
for (i = 0; i < btn.length; i++) {
btnVal = btn[i].value;
btn[i].addEventListener("click", function() { displayNumber(btnVal) }, false);
}
だからあなたのイベントリスナーのすべては非常に同じ変数と対話している、と彼らは最終的にクリックされ得るとき、彼らは」 btnValに割り当てられた最後の値のみが表示されます(btn[btn.length -1].value
)。配列の前のすべての値は失われます。
あなたはこの問題に対処することができ、いくつかの方法があります。イベントがオフになったとき
1)むしろ閉鎖変数に依存するよりも、あなたが要素自体からそれを引くことができます。
for (i = 0; i < btn.length; i++) {
btn[i].addEventListener("click", function (event) {
displayNumber(event.target.value);
});
}
2)関数にイベントリスナの作成を移動し、でbtnValを渡す。それが今、関数のパラメータなので、それが新しいバインディングを取得します。
for (i = 0; i < btn.length; i++) {
createListener(btn[i], btn[i].value);
}
function createListener(element, val) {
element.addEventListener("click", function() { displayNumber(val) }, false);
}
3)IIFEを使用してインラインで行うことができます。
for (i = 0; i < btn.length; i++) {
(function (button) {
button.addEventListener("click", function() { displayNumber(button.value) }, false);
})(btn[i]);
}
EDIT:追加オプション4
4)あなたはES2015を使用することができた場合は、let
を使用しています。ブロックスコープを持ちましょう。ループのたびに新しいバインディングを取得します。
for (i = 0; i < btn.length; i++) {
let btnVal = btn[i].value;
btn[i].addEventListener("click", function() { displayNumber(btnVal) }, false);
}
なぜ、ボタン自体で 'this'の意味でこの関数を定義できないのですか? – tadman