Why is the loop assigning a reference of the last index element to? [duplicate]

Because the actual event occurs sometime in the future after your for loop has already finished running and thus its index is at the last value and any local variables in your function like tagId are also at their last value. You need to create some sort of closure that preserves the value of i or tagId uniquely for each event handler so they each have access to their own value.

There are several different ways to do that, but all involve passing the i value to a function for each event handler.

Here’s one using an IIFE (immediately invoked function expression):

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

A little more common way to do this is to pass the index from the for loop into the closure and do any calculation based on it inside the event handler (though either method works fine) like this:

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

Leave a Comment