Why does replaceChild() behave oddly when replacing one kind of element with another?

javascript

Solution

document.getElementsByTagName is a live access to all the HR elements in the document - it's updated whenever you change the document. You don't get a snapshot of all the HRs in the document whenever you call it.

So, with the first code, you are both incrementing i and reducing the size of hrules.length each time round the loop. This explains why you only see half the steps you expect.

Problem

I am relatively new at javascript, and found an interesting behavior that I can't explain today. I have a custom `<hr>` (with an image) on a website, which displays oddly in IE7 and below. To overcome this, I wanted to use `replaceChild()` in combination with `getElementsByTag()`. Initially, I simply tried to loop over the list, so: ``` var hrules = document.getElementsByTagName('hr'); for (var i=0; i < hrules.length; i++) { var newHrule = document.createElement("div"); newHrule.className = 'myHr'; hrules[i].parentNode.replaceChild(newHrule, hrules[i]); document.write(i); } ``` However, this does not work: it actually only gets half the elements, skipping every other one. Printing `i` gives half-integer values of the actual number of `<hr>` elements in the document (e.g. if there are 7 `<hr/>` elements, it prints 4. By contrast, the following does work: ``` var hrules = document.getElementsByTagName('hr'); var i = 0; while (i < hrules.length) { var newHrule = document.createElement("div"); newHrule.className = 'myHr'; hrules[i].parentNode.replaceChild(newHrule, hrules[i]); document.write(i); } ``` `i` is printed the same number of times as there are hrules in the document (but of course is always 0, since I'm not incrementing it), and the hrules are replaced correctly. I recognize that the `while` here might as well be `while(true)`--it's just going until it runs out of `<hr>` elements, but appears to stop after that (it's not printing any more 0s). I've tried this with a number of different types of elements, and observed that this only occurs when replacing one kind of element with another. I.e., replacing `p` with `div`, `span` with `p`, etc. If I replace `p` with `p`, `div` with `div`, etc. the original example works correctly. Nothing in the documentation I've found (w3schools, various Google search, here, etc.) suggests an obvious answer. What is going on here? First, why does the second example I offered work - is `replaceChild()` iterating over the elements automatically? Second, why is the behavior different for different types of element?

Original source