removeChild Question

P

pbd22

Hi.

Trying to figure this one out.

I want to remove all the "b" elements inside the DIV
tags and NOT the SPAN elements.

I have been trying variations on the below code:

var d = document.getElementById("mypfl");
var d_nested = document.getElementByTagName("b");

d.removeChild(d_nested);

but, I haven't been able to remove the "b" elements successfully.

So, below is an example of a link with the surrounding "b" elements:

<div style="padding-top: 0pt; padding-bottom: 0pt;" id="mypfl"
class=""><b style="background-color: rgb(255, 255, 255);"
class="artop"><b style="border-color: rgb(255, 255, 255); background-
color: rgb(255, 255, 255);" class="rel1"></b><b style="border-color:
rgb(255, 255, 255); background-color: rgb(255, 255, 255);"
class="rel2"></b><b style="border-color: rgb(255, 255, 255);
background-color: rgb(255, 255, 255);" class="rel3"></b><b
style="border-color: rgb(255, 255, 255); background-color: rgb(255,
255, 255);" class="rel4"></b></b>&nbsp;
<span style="border-left: 1px solid rgb(255, 255,
255); border-right: 1px solid rgb(255, 255, 255);" id="pfl"
onclick="newclick(this.id)">My Profile</span>
<b style="background-color: rgb(255, 255, 255);"
class="artop"><b style="border-color: rgb(255, 255, 255); background-
color: rgb(255, 255, 255);" class="rel4"></b><b style="border-color:
rgb(255, 255, 255); background-color: rgb(255, 255, 255);"
class="rel3"></b><b style="border-color: rgb(255, 255, 255);
background-color: rgb(255, 255, 255);" class="rel2"></b><b
style="border-color: rgb(255, 255, 255); background-color: rgb(255,
255, 255);" class="rel1"></b></b></div>
 
D

David Golightly

Hi.

Trying to figure this one out.

I want to remove all the "b" elements inside the DIV
tags and NOT the SPAN elements.

I have been trying variations on the below code:

var d = document.getElementById("mypfl");
var d_nested = document.getElementByTagName("b");

d.removeChild(d_nested);

but, I haven't been able to remove the "b" elements successfully.

So, below is an example of a link with the surrounding "b" elements:

<div style="padding-top: 0pt; padding-bottom: 0pt;" id="mypfl"
class=""><b style="background-color: rgb(255, 255, 255);"
class="artop"><b style="border-color: rgb(255, 255, 255); background-
color: rgb(255, 255, 255);" class="rel1"></b><b style="border-color:
rgb(255, 255, 255); background-color: rgb(255, 255, 255);"
class="rel2"></b><b style="border-color: rgb(255, 255, 255);
background-color: rgb(255, 255, 255);" class="rel3"></b><b
style="border-color: rgb(255, 255, 255); background-color: rgb(255,
255, 255);" class="rel4"></b></b>&nbsp;
<span style="border-left: 1px solid rgb(255, 255,
255); border-right: 1px solid rgb(255, 255, 255);" id="pfl"
onclick="newclick(this.id)">My Profile</span>
<b style="background-color: rgb(255, 255, 255);"
class="artop"><b style="border-color: rgb(255, 255, 255); background-
color: rgb(255, 255, 255);" class="rel4"></b><b style="border-color:
rgb(255, 255, 255); background-color: rgb(255, 255, 255);"
class="rel3"></b><b style="border-color: rgb(255, 255, 255);
background-color: rgb(255, 255, 255);" class="rel2"></b><b
style="border-color: rgb(255, 255, 255); background-color: rgb(255,
255, 255);" class="rel1"></b></b></div>

Whoa! How about some newlines here?

While we're at it, how about pulling out all those style attributes
into an external stylesheet?

To your question:

You're having problems because you can't use removeChild to remove a
NodeCollection or anything but an HTMLElement that's a direct child of
the parent node in question. Also, in your example, not all "b" tags
are direct children of your div#mypfl. However, you *can* write:

var d = document.getElementById('mypfl');
for (var i=0, cn; cn=d.childNodes[i++]; ) {
// nodeType == 1 means it's an ElementNode; childNodes might also
// include TextNodes, CommentNodes, or any other type of node
// you might have in your markup
if (cn.nodeType == 1 && cn.tagName.toUpperCase == 'B') {
d.removeChild(cn);
}
}

-David
 
T

Thomas 'PointedEars' Lahn

pbd22 said:
I want to remove all the "b" elements inside the DIV
tags and NOT the SPAN elements.

I have been trying variations on the below code:

var d = document.getElementById("mypfl");
var d_nested = document.getElementByTagName("b");

For good reason, the method is called `getElement*s*ByTagName'.

http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-A6C9094
d.removeChild(d_nested);

If I would assume that the above is merely a typo (copy and paste from the
original code would help to avoid such mistakes), Node::removeChild() of
course accepts only *one* Node object reference as argument, as it is
specified in W3C DOM Level 1+:

http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-1734834066
but, I haven't been able to remove the "b" elements successfully.

If you had had a look at the JavaScript console before posting as
recommended in the FAQ and FAQ Notes, your mistake would have been clear to
you already.
So, below is an example of a link with the surrounding "b" elements:

I will pretty-print that for better legibility, which you should have done.
Note that by doing this I introduce whitespace which would be parsed as a
text node; however, that has no relevance to your problem or the solution
presented below.

<div style="padding-top: 0pt; padding-bottom: 0pt;" id="mypfl" class="">
<b style="background-color: rgb(255, 255, 255);" class="artop">
<b style="border-color: rgb(255, 255, 255); background-color: rgb(255,
255, 255);" class="rel1"></b>
<b style="border-color: rgb(255, 255, 255); background-color: rgb(255,
255, 255);" class="rel2"></b>
<b style="border-color: rgb(255, 255, 255); background-color: rgb(255,
255, 255);" class="rel3"></b>
<b style="border-color: rgb(255, 255, 255); background-color: rgb(255,
255, 255);" class="rel4"></b>
</b>&nbsp;
<span style="border-left: 1px solid rgb(255, 255, 255); border-right:
1px solid rgb(255, 255, 255);" id="pfl" onclick="newclick(this.id)"
My Profile</span>
<b style="background-color: rgb(255, 255, 255);" class="artop">$
<b style="border-color: rgb(255, 255, 255); background-color: rgb(255,
255, 255);" class="rel4"></b>
<b style="border-color: rgb(255, 255, 255); background-color: rgb(255,
255, 255);" class="rel3"></b>
<b style="border-color: rgb(255, 255, 255); background-color: rgb(255,
255, 255);" class="rel2"></b>
<b style="border-color: rgb(255, 255, 255); background-color: rgb(255,
255, 255);" class="rel1"></b>
</b>
</div>

To remove all `b' elements here, you will have to iterate over
the *NodeList* that Node::getElementsByTagName() returns.

for (var i = d_nested.length; i--;)
{
var o = d_nested;
o.parentNode.removeChild(o);
}


HTH

PointedEars
 
T

Thomas 'PointedEars' Lahn

David said:
var d = document.getElementById('mypfl');
for (var i=0, cn; cn=d.childNodes[i++]; ) {

I think this is error-prone because NodeList objects such as
Node::childNodes are *live*.
// nodeType == 1 means it's an ElementNode; childNodes might also
// include TextNodes, CommentNodes, or any other type of node
// you might have in your markup
if (cn.nodeType == 1

Since only element nodes have a `tagName' property that could evaluate to
`b' or `B', that test is unnecessary.
&& cn.tagName.toUpperCase == 'B') {

All will fail because toUpperCase() is a method to be called and a Function
object reference string-converted does not equal 'B'. toLowerCase() would
be more efficient here, but the test was not necessary if the NodeList
object retrieved before was used instead of childNodes.
d.removeChild(cn);

This will not remove `b' elements that are descendants of elements of
another type than `b'.


PointedEars
 
R

RobG

Hi.

Trying to figure this one out.

I want to remove all the "b" elements inside the DIV
tags and NOT the SPAN elements.

I have been trying variations on the below code:

var d = document.getElementById("mypfl");
var d_nested = document.getElementByTagName("b");

d.removeChild(d_nested);

but, I haven't been able to remove the "b" elements successfully.

So, below is an example of a link with the surrounding "b" elements:
[...]

Simply removing the b elements will also remove their content. If
what you are trying to do is remove them but keep the content, I think
the best method is to put the content of the b element into a span,
then replace the b with the span. The following should get you
started:

function removeBs(rootNodeID){
var bNode, allBnodes, rootNode, newNode;
if (!document ||
!document.getElementById ||
!document.getElementsByTagName ||
!document.createElement){
return;
}

if (typeof rootNodeID == 'string'){
rootNode = document.getElementById(rootNodeID);
} else if (typeof rootNodeID == 'object') {
rootNode = rootNodeID;
} else {
rootNode = document;
}

allBnodes = rootNode.getElementsByTagName('b');

// allBnodes is live, so as remove b elements from document,
// they are also removed from the collection
while (allBnodes.length) {
bNode = allBnodes[0];
newNode = document.createElement('span');

// Put all content of b into a span
while (bNode.firstChild){
newNode.appendChild(bNode.firstChild);
}

// Replace the (now empty) b with the span
bNode.parentNode.replaceChild(newNode, bNode);
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,158
Messages
2,570,882
Members
47,414
Latest member
djangoframe

Latest Threads

Top