By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
438,480 Members | 1,808 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 438,480 IT Pros & Developers. It's quick & easy.

Recursive function : driving me crazy...

P: n/a
Hello
I'm trying to display all DIV tags of a document :
Example :

+ <DIV id="1">
- <DIV id="1-1"></DIV>
</DIV>

+ <DIV id="2">
- <DIV id="2-1"></DIV>
+ <DIV id="2-2"></DIV>
- <DIV id="2-2-1"></DIV>
- <DIV id="2-2-2"></DIV>

etc...

I can retrieve all DIV using getElementsByTagName, but I don't know how
deep they can be nested.
I have no idea how to store informations such as : does a div has children
? if yes, how many ? in turn do the children have children ? At what level
is each DIV ? etc
Only a recursive function could do that, I think

Any help appreciated
Thanks.

Jul 20 '05 #1
Share this Question
Share on Google+
6 Replies


P: n/a
"Phil" <pa*******@pasdemail.com> wrote in message
news:Lo********************@giganews.com...
Hello
I'm trying to display all DIV tags of a document :
Example :

+ <DIV id="1">
- <DIV id="1-1"></DIV>
</DIV>

+ <DIV id="2">
- <DIV id="2-1"></DIV>
+ <DIV id="2-2"></DIV>
- <DIV id="2-2-1"></DIV>
- <DIV id="2-2-2"></DIV>

etc...

I can retrieve all DIV using getElementsByTagName, but I don't know how
deep they can be nested.
I have no idea how to store informations such as : does a div has children ? if yes, how many ? in turn do the children have children ? At what level
is each DIV ? etc
Only a recursive function could do that, I think

Any help appreciated
Thanks.

Your example above was missing a </DIV> tag and had another misplaced.

I may not understand your problem.

You say that you are "trying to display all DIV tags of a document" and that
you "can retrieve all DIV using getElementsByTagName"; what does it matter
how deep they are nested?

Below is a page that displays the id's of all <DIV> tags. Watch for
word-wrap.

<html>
<head>
<title>getElems.htm</title>
</head>
<body>
<DIV id="1">
<DIV id="1-1"></DIV>
</DIV>
<DIV id="2">
<DIV id="2-1"></DIV>
<DIV id="2-2">
<DIV id="2-2-1"></DIV>
<DIV id="2-2-2"></DIV>
</DIV>
</DIV>
<script language="javascript" type="text/javascript">
<!--
var divs = document.getElementsByTagName("DIV");
var what = "DIV tags:\n";
for (var i=0; i<divs.length; i++) {
what += "\n" + divs[i].id;
}
alert(what);
// -->
</script>
</body>
</html>
Jul 20 '05 #2

P: n/a
I may not understand your problem.

You say that you are "trying to display all DIV tags of a document" and that you "can retrieve all DIV using getElementsByTagName"; what does it matter
how deep they are nested?

Below is a page that displays the id's of all <DIV> tags. Watch for
word-wrap.


Thanks for your example, but I can already made this. What I want is really
displaying (document.write) the tree, with nodes, children and so forth
(Missing closing tags is not the point, I write this on the fly and I know
they are missing)

So if a div has children, I need to write the + sign, then the nested
children (if any) indented, etc
+ <DIV id="2">
- <DIV id="2-1"></DIV>
+ <DIV id="2-2"></DIV>
- <DIV id="2-2-1"></DIV>
- <DIV id="2-2-2"></DIV>
</DIV>


Jul 20 '05 #3

P: n/a
"Phil" <pa*******@pasdemail.com> writes:
Thanks for your example, but I can already made this. What I want is really
displaying (document.write) the tree, with nodes, children and so forth
(Missing closing tags is not the point, I write this on the fly and I know
they are missing)


I'll just write it as a string here, I'm sure you can convert the output
to your needs.

I can see two methods. One uses the document.getElementsByTagName("div")
collection and finds the structure by checking which elements are inside
each other. The other uses recursive descent on the tree. In both cases,
I build a datastructure of nodes on the form
node ::= {elem: DivNode, children: [array of divs nested inside DivNode]}

Using div collection, assuming that the divs are in the order the
start tags occour in the document (as I believe they should be):
---
// function that checks whether node2 is a predecessor of node1
function parentOf(node1,node2) {
while(node1!=null) {
if (node1 == node2) {return true;}
node1 = node1.parentNode;
}
return false;
}

function findDivsNest(elem) {
var divs = elem.getElementsByTagName("div");
var stack = [];
var topNode = {elem:elem,children:[]};
var currentNode = topNode;
for (var i = 0; i<divs.length;i++) {
var div = divs[i];
while (!parentOf(div,currentNode.elem)) {
currentNode = stack.pop();
}
var thisNode = {elem:div,children:[]};
currentNode.children.push(thisNode);
stack.push(currentNode);
currentNode = thisNode;
}
return topNode.children;
}
---

Recursive descent version:
---
function findDivsRec(node) {
if (node.nodeType != 1 && node.nodeType != 9) {
return []; // non-element, non-document node
}
var divs = [];
for (var chld = node.firstChild; chld != null; chld=chld.nextSibling) {
divs = divs.concat(findDivsRec(chld));
}
if (/^div$/i.test(node.tagName)) {
return [{elem:node,children:divs}];
} else {
return divs;
}
}
---

An example of how to output the data as text:
---
function divsToLines(divs,indent) {
indent = indent || "";
var nextIndent;
var result = [];
for (var i=0;i<divs.length;i++) {
var div=divs[i];
if (div.children.length > 0) {
nextIndent = nextIndent || indent + " "; // calc once
result.push(indent+" + <div id=\""+div.elem.id+"\">");
result = result.concat(divsToLines(div.children,nextIndent) );
result.push(indent+" <\/div>");
} else {
result.push(indent+" - <div id=\""+div.elem.id+"\"><\/div>");
}
}
return result;
}

function divsToString(divs) {
return divsToLines(divs).join("\n");
}
---

You can then test it with

alert(divsToString(findDivsRec(document)));
or
alert(divsToString(findDivsNest(document)));

If you want the output to be HTML, it's easy to fix.
/L
--
Lasse Reichstein Nielsen - lr*@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
Jul 20 '05 #4

P: n/a
Thank you. Have to study your code...it's a hard one for me :-)
"Lasse Reichstein Nielsen" <lr*@hotpop.com> a écrit dans le message de news:
hd**********@hotpop.com...
"Phil" <pa*******@pasdemail.com> writes:
Thanks for your example, but I can already made this. What I want is really displaying (document.write) the tree, with nodes, children and so forth
(Missing closing tags is not the point, I write this on the fly and I know they are missing)


I'll just write it as a string here, I'm sure you can convert the output
to your needs.

Jul 20 '05 #5

P: n/a
"Phil" <pa*******@pasdemail.com> wrote in message
news:_9********************@giganews.com...
I may not understand your problem.

You say that you are "trying to display all DIV tags of a document" and that
you "can retrieve all DIV using getElementsByTagName"; what does it matter how deep they are nested?

Below is a page that displays the id's of all <DIV> tags. Watch for
word-wrap.


Thanks for your example, but I can already made this. What I want is

really displaying (document.write) the tree, with nodes, children and so forth
(Missing closing tags is not the point, I write this on the fly and I know
they are missing)

So if a div has children, I need to write the + sign, then the nested
children (if any) indented, etc
+ <DIV id="2">
- <DIV id="2-1"></DIV>
+ <DIV id="2-2"></DIV>
- <DIV id="2-2-1"></DIV>
- <DIV id="2-2-2"></DIV>
</DIV>

Try this as-is; watch for word-wrap.
It may not be that elegant but it works.
<html>
<head>
<title>getElems.htm</title>
</head>
<body>

<DIV id="1">
<DIV id="1-1"></DIV>
</DIV>
<DIV id="2">
<DIV id="2-1"></DIV>
<DIV id="2-2">
<DIV id="2-2-1"></DIV>
<DIV id="2-2-2"></DIV>
</DIV>
</DIV>
<DIV id="3"></DIV>

<script language="javascript" type="text/javascript">
<!--
var diva = new Array();
var divi = 0;
var divs = document.getElementsByTagName("DIV");
var save = "|";
for (var i=0; i<divs.length; i++) {
if (save.indexOf("|"+divs[i].id+"|") < 0) {
getElement(divs[i],0);
}
}
function getElement(tag) {
var tags = tag.getElementsByTagName("DIV");
if (tag.childNodes[0] != null) {
save += tag.id + "|";
divi++;
diva[divi] = "+ " + tag.id;
for (var j=0; j<tag.childNodes.length; j++) {
getElement(tag.childNodes[j]);
save += tag.childNodes[j].id + "|";
}
} else {
divi++;
diva[divi] = "- " + tag.id;
}
}
var divx = "DIV tags:<br>";
for (var x=1; x<diva.length; x++) {
divx += "<br>" + diva[x];
}
document.write("<pre>" + divx + "</pre>");
// -->
</script>
</body>
</html>
Jul 20 '05 #6

P: n/a
Thanks a lot. I let you know how things go

"McKirahan" <Ne**@McKirahan.com> a écrit dans le message de news:
ODZGb.656303$HS4.4674451@attbi_s01...
"Phil" <pa*******@pasdemail.com> wrote in message
news:_9********************@giganews.com...

Jul 20 '05 #7

This discussion thread is closed

Replies have been disabled for this discussion.