"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.'