MaxelRus MaxelRus - 1 month ago 6
HTML Question

Trigger event for each object

I want website to change class of an element if it is filled. So, when user

blur
s out of an input field the program checks if it has any value and if yes adds a class. The problem is to pass this behaviour to each element in class' collection.

var input = document.getElementsByClassName('input');
contentCheck = function(i){
if(input[i].value>0) input[i].classList.add('filled');
else input[i].classList.remove('filled');
};
for(var i=0; i<input.length; i++) {
input[i].addEventListener('blur',contentCheck(i));
}


This works once after reloading the page (if there's any content in cache), but
contentCheck()
should trigger each time you leave the focus.

Answer

You've half-applied the "closures in loops" solution to that code, but you don't need the closures in loops solution, just use this within contentCheck and assign it as the handler (rather than calling it and using its return value as the handler):

var input = document.getElementsByClassName('input');
var contentCheck = function(){ // <== No `i` argument (and note the `var`)
    // Use `this` here
    if(this.value>0) this.classList.add('filled');
    else this.classList.remove('filled');
};
for(var i=0; i<input.length; i++) {
    input[i].addEventListener('onkeypress',contentCheck);
    // No () here -------------------------------------^
}

Side note: classList has a handy toggle function that takes an optional flag:

var contentCheck = function(){
    this.classList.toggle('filled', this.value > 0);
};

If you needed the "closures in loops" solution (again, you don't, but just for completeness), you'd have contentCheck return a function that did the check:

var input = document.getElementsByClassName('input');
var makeContentCheckHandler  = function(i){
    return function() {
        if(input[i].value>0) input[i].classList.add('filled');
        else input[i].classList.remove('filled');
    };
};
for(var i=0; i<input.length; i++) {
    input[i].addEventListener('onkeypress', makeContentCheckHandler(i));
}

Note I changed the name for clarity about what it does.

Comments