Note that there are some explanatory texts on larger screens.

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

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload