Walk the DOM
Expand/Collapse DOM items
by roge roge
HTML
<a href="javascript:void(0);" title="Déplier" onclick="showLevel(document.getElementById('Data'), 10)"> Open all </a>
<a href="javascript:void(0);" title="Plier" onclick="showLevel(document.getElementById('Data'), 0)"> Close all </a>
<a href="javascript:void(0);" title="Plier" onclick="computeMaxLevel(document.getElementById('Data'))"> Compute MaxLevel </a>
<pre id="Data">
<span class="OB" style="display: inline;">{</span>
<a class="ExpanderOpened" title="Plier/Déplier" onclick="toggleContainer(this)">course: <span class="NB">12345</span></a>
<span class="Container" style="display: inline;">
<a class="ExpanderOpened" title="Plier/Déplier" onclick="toggleContainer(this)">Modules</a>:
<span class="Container" style="display: inline;">
<span class="LI" style="display: inline;">[</span>
<span class="OB" style="display: inline;">{</span>
<a class="ExpanderOpened" title="Plier/Déplier" onclick="toggleContainer(this)">Module: <span class="NB">1</span></a>
<span class="Container" style="display: inline;">
<a class="ExpanderOpened" title="Plier/Déplier" onclick="toggleContainer(this)">Sequences</a>:
<span class="Container" style="display: inline;">
<span class="LI" style="display: inline;">[</span>
<span class="OB" style="display: inline;">{</span>
<a class="ExpanderOpened" title="Plier/Déplier" onclick="toggleContainer(this)">Sequence<span class="NB">1</span></a>
<a class="ExpanderOpened" title="Plier/Déplier" onclick="toggleContainer(this)">Sequence<span class="NB">1</span></a>
<span class="OB" style="display: inline;">}</span>
<span class="LI" style="display: inline;">]</span>
</span>
</span>
<span class="OB" style="display: inline;">},</span>
...
CSS
.OB { /* ObjectBrace */
color:#00AA00;
font-weight:bold;
}
.LI { /* ObjectBrace */
color:#0033FF;
font-weight:bold;
}
PRE.CodeContainer {
margin-left:10px;
line-height: 16pt;
}
A.ExpanderOpened {
cursor: pointer;
color: #060;
border-bottom: 1px solid #999;
}
A.ExpanderClosed {
cursor: pointer;
color: #800;
font-weight: bold;
border-bottom: 1px solid #666;
}
A.ExpanderOpened:hover, A.ExpanderClosed:hover {
border-radius: 4px;
background: #ddd;
}
JavaScript
/*
Node.ELEMENT_NODE == 1 ( element node )
Node.ATTRIBUTE_NODE == 2 ( node attribute )
Node.TEXT_NODE == 3 ( text node )
Node.CDATA_SECTION_NODE == 4 ( CDATA section node )
Node.ENTITY_REFERENCE_NODE == 5 ( node reference to an entity )
Node.ENTITY_NODE == 6 ( Feature node )
Node.PROCESSING_INSTRUCTION_NODE == 7 ( processing instruction node )
Node.COMMENT_NODE == 8 ( comment node )
Node.DOCUMENT_NODE == 9 ( document node )
Node.DOCUMENT_TYPE_NODE == 10 ( Document Type node )
Node.DOCUMENT_FRAGMENT_NODE == 11 ( node document fragment )
Node.NOTATION_NODE == 12 ( node notation )
*/
function computeMaxLevel(obj) {
var maxLevel=0;
function walkTheContainer(node, depth, func) {
depth = func(node, depth);
node = node.firstChild;
while (node) {
//console.log(depth + "+ Node : " + node.nodeName + " ==> " + node.className);
walkTheContainer(node, depth, func);
node = node.nextSibling;
}
}
walkTheContainer(obj, 0, function (node, depth) {
if (node.className == "Container") {
depth++;
maxLevel = Math.max (maxLevel, depth);
//console.log(" ++++ maxLevel " + maxLevel + " - Container " );
}
return depth;
});
alert("maxLevel = " + maxLevel);
}
function showLevel(obj, lev) {
function walkTheContainer(node, depth, maxDepth, func) {
if (depth > maxDepth + 1) return;
depth = func(node, depth, maxDepth);
node = node.firstChild;
while (node) {
walkTheContainer(node, depth, maxDepth, func);
node = node.nextSibling;
}
}
walkTheContainer(obj, 1, lev, function (node, depth, maxDepth) {
switch (node.className) {
case "ExpanderOpened" :
case "ExpanderClosed" :
node.className = (depth > maxDepth) ? "ExpanderClosed" : "ExpanderOpened";
console.log(depth + "+ Expander : " + node.innerHTML + " ==> " + node.className);
break;
case "Container" :
node.style.display = (depth > maxDepth) ? "none" : "inline";
console.log(depth + " Container : " + node.style.display...