すべてのタグにイベントリスナーを追加したいと思います。各タグは、偶数がトリガーされたときにパラメーターとしてそれ自体への参照を渡します。これが私が書いた関数です:
function validateDigitsFeature()
{
// Add the event listeners to input tags
// Get the array of input tags
var inputTags = document.getElementsByClassName('validateInput');
var tagId;
// Loop through them, adding the onkeypress event listener to each one
for (var i = 0; i < inputTags.length; i++)
{
// Give each input element an id
tagId = inputTags[i].id = 'input_id_' + i;
inputTags[i].addEventListener('keyup', function(){isNumberOrDot(event, tagId);}, false);
}
}
基本的に、関数は次のことを行う必要があります。
onkeyup
イベントリスナーを追加しisNumberOrDot(event, tagId)
ます。onkeyupイベントが追加されますが、それぞれのハンドラーは常にtagId
配列の最後の要素のを参照しています。
コード/ロジックの何が問題になっていますか?そして、どのようにそれを修正することができますか?
確かに、この問題はループ内のJavaScriptクロージャに関連していますが、この質問にはもっと一般的な答えがありますが、使用されているイベントリスナーに固有です。より高度な開発者にとっては、この問題に一般的な解決策を適用するのは簡単かもしれません。しかし、私にとって、他の解決策はまだ完全な説明を提供しておらず、機能さえしていませんでした。
前もって感謝します。
実際のイベントは、for
ループの実行がすでに終了した後の将来のある時点で発生するため、そのインデックスは最後の値になり、関数内のローカル変数tagId
も最後の値になります。各イベントハンドラーの値を保持する、i
またはtagId
イベントハンドラーごとに一意に保持して、それぞれが独自の値にアクセスできるようにする、ある種のクロージャーを作成する必要があります。
これを行うにはいくつかの異なる方法がありますが、すべての方法で、i
各イベントハンドラーの関数に値を渡す必要があります。
IIFE(即時呼び出し関数式)を使用したものは次のとおりです。
function validateDigitsFeature()
{
// Add the event listeners to input tags
// Get the array of input tags
var inputTags = document.getElementsByClassName('validateInput');
// Loop through them, adding the onkeypress event listener to each one
for (var i = 0; i < inputTags.length; i++)
{
// Give each input element an id
(function() {
// creates a unique function context for each event handler so the
// value of tagId is unique for each event handler
var tagId = inputTags[i].id = 'input_id_' + i;
inputTags[i].addEventListener('keyup', function(){isNumberOrDot(event, tagId);}, false);
})();
}
}
これを行うもう少し一般的な方法は、for
ループからクロージャーにインデックスを渡し、イベントハンドラー内でそれに基づいて計算を行うことです(どちらの方法でも正常に機能します)。
function validateDigitsFeature()
{
// Add the event listeners to input tags
// Get the array of input tags
var inputTags = document.getElementsByClassName('validateInput');
// Loop through them, adding the onkeypress event listener to each one
for (var i = 0; i < inputTags.length; i++)
{
// Give each input element an id
(function(index) {
// passes the `for` loop index into a function closure
// so it is uniquely preserved for each event handler
inputTags[index].addEventListener('keyup', function(){
isNumberOrDot(event, inputTags[index].id = 'input_id_' + index);
}, false);
})(i);
}
}
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加