Reputation: 20698
JSFiddle URL: http://jsfiddle.net/sFe45/
Code:
<html>
<head>
<title>Foo</title>
<script type="text/javascript">
var target;
var anchor;
function removeTags(node){
for (var i = 0; i < node.childNodes.length; i++) {
var childNode = node.childNodes[i];
if (childNode.nodeType == 1) {
node.removeChild(childNode);
continue;
}
removeTags(childNode);
}
}
window.onload = function() {
target = document.getElementById('target');
anchor = document.getElementById('anchor');
anchor.onclick = function() {
removeTags(target);
}
}
</script>
</head>
<body>
<div id="target">
<p>
<a href="#" id="anchor">Remove tags</a>
</p>
Text
<p>Para 1</p>
<p>Para 2</p>
<p>Para 3</p>
<p>Para 4</p>
<p>Para 5</p>
<p>Para 6</p>
<p>Para 7</p>
<p>Para 8</p>
<p>Para 9</p>
<p>Para 10</p>
Text
</div>
</html>
As you will notice in the JSFiddle URL, when you click the "Remove tags" link, removeTags()
fails to remove alternate paragraph elements. The reason is when a removeTags
removes a child node from its parent, the remaining child nodes shift one place to left in node.childNodes
array.
How can this be fixed in a neat way?
Upvotes: 0
Views: 2151
Reputation: 1075189
Count backward:
for (var i = node.childNodes.length - 1; i >= 0; i--) {
Alternately, you can use lastChild
and previousSibling
:
var prev;
for (var child = node.lastChild; child; child = prev) {
prev = child.previousSibling;
if (child.nodeType == 1) {
node.removeChild(child);
continue;
}
removeTags(child);
}
Separately:
...the remaining child nodes shift one place to left in
node.childNodes
array...
NodeList
s are not arrays.
Upvotes: 3