NoName84
NoName84

Reputation: 407

Javascript and the DOM issues

I am having a trouble using Vanilla Javascript and the DOM. In my html code i have some p elements and some h2 elements. I am trying to target them with javascript just to train of using the DOM. Here is my Javascript code:

var allP = document.querySelectorAll("p");
var h = document.querySelectorAll("h2");

for ( i=0; i <= allP.length; i++){
    allP[i].classList.add("hello"), allP[i].style.color = "red";
};

for (i=0; i<=h.length; i++){
    h[i].style.color = "orange";
}

The P tag elements are getting the hello class and the style color to red. However when i continue with the h2 tag they do not get their color to change. Moreover if i remove the allP var and the for loop, the h2 for loop works fine. Anyone can explain why this is happening? Also i have some li elements and some a tags but as soon as the first for loop kicks in the other for loops below the first one does not work.

Thanks

Upvotes: 0

Views: 74

Answers (4)

Justin
Justin

Reputation: 2970

As other have pointed out, you have a scoping issue. You can still use i for both loops, just declare it with var so its not globally scoped. There's also an issue with i <= arr.length you need to make it i <= arr.length - 1.

var allP = document.querySelectorAll("p");
var h = document.querySelectorAll("h2");

for ( var i=0; i <= h.length - 1; i++){
    h[i].style.color = "orange";
}

for ( var i=0; i <= allP.length - 1; i++){
    allP[i].classList.add("hello"); 
    allP[i].style.color = "red";
};

Update I was incorrect on the scoping, that's not the issue here. I assumed that var declaration inside loop initialization made variables that were local to the loop, but they're actually scoped to the same scope the loop is running in.

The problem occurs only because of the issue with using h.length instead of h.length - 1 (or using < instead of <=).

Upvotes: 0

Lionel T
Lionel T

Reputation: 1597

Change i < xxx.length in the loops length to avoid an error. The length of the loop for example could be 3 so the loop will target the elements allP[0], allP[1] and allP[2].

var allP = document.querySelectorAll("p");
var h = document.querySelectorAll("h2");
var i;
for ( i=0; i < allP.length; i++){
  allP[i].classList.add("hello");
  allP[i].style.color = "red";
};

for (i=0; i < h.length; i++){
  h[i].style.color = "orange";
}
<p>p1</p>
<p>p2</p>
<p>p3</p>

<h2>h2a</h2>
<h2>h2b</h2>
<h2>h2c</h2>
<h2>h2d</h2>

Upvotes: 1

Barmar
Barmar

Reputation: 780974

The problem is that you're getting an error in the first loop, so the second loop never executes. You need to change i <= allP.length to i < allP.length (and similarly for the second loop). Array indexes run from 0 to length-1, but you're trying to assign to properties of allP[allP.length]. Since this is undefined, calling undefined.classList.add() gets an error.

Also, you should separate the two operations with ;, not ,. It happens to work the way you wrote it, because of the way the comma operator works, but it's not good style -- this is not one of the situations where the comma operator is needed.

And it's good practice to declare loop variables local with var.

for (var i=0; i < allP.length; i++){
    allP[i].classList.add("hello");
    allP[i].style.color = "red";
};

for (i=0; i < h.length; i++){
    h[i].style.color = "orange";
}

Upvotes: 1

Tudor Ilisoi
Tudor Ilisoi

Reputation: 2944

Try using another variable in the second loop, for example j:

var allP = document.querySelectorAll("p");
var h = document.querySelectorAll("h2");

for (var i=0; i <= allP.length; i++){
    allP[i].classList.add("hello"), allP[i].style.color = "red";
};

for (var j=0; j<=h.length; j++){
    h[j].style.color = "orange";
}

Upvotes: 0

Related Questions