Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

QuerySelectorAll not working with onclick event

Scenario

I've got some text inputs and I want them to have a width of 500px when they're clicked.

My code

var inputs = document.querySelectorAll("input[type=text]")
for(i=0; i<inputs.length; i++){
	inputs[i].onclick = function(){
		inputs[i].style.width = "500px";
	}
}
<input type="text" id="sometext">

What's not working

On chrome console, I'm getting "Cannot read property 'style' of undefined" on the following line: inputs[i].style.width = "500px"; when I click on the input.

My question

How can I fix my code?

like image 786
Stubborn Avatar asked Dec 27 '15 16:12

Stubborn


1 Answers

"Cannot read property 'style' of undefined"

The reason you're seeing this error is because the for loop has already ended and i is outside of the bounds of the inputs NodeList when the click event is fired. In other words, since the last element's index in the array is one less than the length, inputs[i] is undefined since i is equal to the length of the NodeList when the click event listener is fired.

To work around this, you could change inputs[i] to this in order to access the clicked element. In doing so, you avoid having to use i (which is what was causing the problem):

var inputs = document.querySelectorAll("input[type=text]")
for (i = 0; i < inputs.length; i++) {
  inputs[i].addEventListener('click', function() {
    this.style.width = "500px";
  });
}

Alternatively, you could use an IIFE in order to pass the value of i on each iteration:

var inputs = document.querySelectorAll("input[type=text]")
for (i = 0; i < inputs.length; i++) {
  (function(i) {
    inputs[i].addEventListener('click', function() {
      inputs[i].style.width = "500px";
    });
  })(i);
}

You could also use the .bind() method to pass the value of i:

var inputs = document.querySelectorAll("input[type=text]")
for (i = 0; i < inputs.length; i++) {
  inputs[i].addEventListener('click', function(i) {
    inputs[i].style.width = "500px";
  }.bind(this, i));
}
like image 92
Josh Crozier Avatar answered Oct 11 '22 02:10

Josh Crozier