w8tcher
w8tcher

Reputation: 3

loop only executed one time

var el = document.getElementById("aufgaben");
var kind = el.firstChild;
var i = 0;
while (kind) {
  alert(i + kind);
  kind.style.backgroundColor = "orange";
  kind = kind.nextSibling;
  i++;
}
<ul id="aufgaben">
  <li class="offen">aufgabe1<a href="#"> erledigen</a></li>
  <li class="offen">aufgabe2<a href="#"> erledigen</a></li>
  <li class="offen">aufgabe3<a href="#"> erledigen</a></li>
  <li class="offen">aufgabe4<a href="#"> erledigen</a></li>
</ul>

the loop works properly when the line 'kind.style.backgroundColor = "orange' is marked as a comment. when is line is active, only one alert appears and no child of the gets the orange backgroundcolor.

Upvotes: 0

Views: 39

Answers (2)

Arel Lin
Arel Lin

Reputation: 928

The firstChild property of a DOM returns the first CHILD NODE of that DOM, not the first CHILD ELEMENT.

CHILD NODE includes text nodes.

Add this code console.log(el.childNodes) to check the difference, you'll know what I'm saying.

In this case, kind will be the empty text node which is before the first element.
If you want to get the first element, try to modify line:2 like below.
var kind = el.firstElementChild;
Then you will get what you want.

And if you want to jump to next element sibling, modify line:7 to kind = kind.nextElementSibling;.

It should work as you expected.

Upvotes: 0

epascarello
epascarello

Reputation: 207557

Issue here is firstChild and nextSibling return text nodes and elements. So you are selecting the textnode between the ul and the li. So to get around this, use the element selector versions that skip the textnodes.

var el = document.getElementById("aufgaben");
var kind = el.firstElementChild;
var i = 0;
while (kind) {
  kind.style.backgroundColor = "orange";
  kind = kind.nextElementSibling;
  i++;
}
<ul id="aufgaben">
  <li class="offen">aufgabe1<a href="#"> erledigen</a></li>
  <li class="offen">aufgabe2<a href="#"> erledigen</a></li>
  <li class="offen">aufgabe3<a href="#"> erledigen</a></li>
  <li class="offen">aufgabe4<a href="#"> erledigen</a></li>
</ul>

To do it with your code, you would have to check the node type

var el = document.getElementById("aufgaben");
var kind = el.firstChild;
var i = 0;
while (kind) {
  if(kind.nodeType==1) {  // make sure it is an element node
    kind.style.backgroundColor = "orange";
  }
  kind = kind.nextSibling;
  i++;
}
<ul id="aufgaben">
  <li class="offen">aufgabe1<a href="#"> erledigen</a></li>
  <li class="offen">aufgabe2<a href="#"> erledigen</a></li>
  <li class="offen">aufgabe3<a href="#"> erledigen</a></li>
  <li class="offen">aufgabe4<a href="#"> erledigen</a></li>
</ul>

Upvotes: 1

Related Questions