Search code examples
javascriptvariablesaddeventlistenerinnerhtml

Passing variables through addEventListener


I am trying to add event to all inputs, get the value (number) from those and insertHtml them into span elements.

This is my javascript code. I have no idea how to pass the variables.

var input_selector = document.querySelectorAll('.coins_n'); // input number elements
var price_selector = document.querySelectorAll('.price'); // span elements

for(var i = 0; i <= input_selector.length; i++) {
    var input = input_selector[i];
    var price = price_selector[i];

    input.addEventListener('input', function(){
        console.log(price); // not working
        console.log(input); // not working
        price.innerHTML = input.value; // not working
    })
}

Solution

  • The problem here has to do with scoping of your variables. var is a weird one, whose scope isn't really limited to the block, but to the containing function. The following two are (essentially) the same:

    var input;
    var i = 0;
    
    for(; i < input_selector.length; i++) input = input_selector[i];
    

    and

    for(var i = 0; i < input_selector.length; i++) var input = input_selector[i];
    

    both create a variable named input in global scope, and then update that variable. That means that any functions that wants to read input later will just read the last version of input, and not the version at the time you defined the handler you would trigger later.

    let, however, is block scoped, and your for loop is a block. So defining let input inside the for loop will mean that input is defined uniquely for every iteration of the loop, since every time the block gets executed a new scope is created for everything in there.

    The same is true for var i = 0 in your for loop - any handler that calls it later will just log the last global value of i, but if you use let, that's not the case and every iteration of the loop has its own i. So your code could simply be reduced to this:

    const input_selector = document.querySelectorAll('.coins_n');
    const price_selector = document.querySelectorAll('.price');
    
    for( let i = 0; i < input_selector.length; i++ ){
    
        input_selector[i].addEventListener('input', event => {
    
            price_selector[i].innerHTML = event.target.value;
    
        });
    
    }
    

    This is pretty complex to explain once you start typing it out, so better read what other have already written at something like MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let