Как сделать сворачивание / разворачивание веток
В теме "Как сделать сворачивание / разворачивание веток DOM на JavaScript?" представлен отличный пример раскрывающегося списка.
Подскажите, пожалуйста, как сделать так, чтобы подобный список открывался в закрытом (свернутом) виде, а раскрывалась только та ветка, на которую кликаешь?
Ответы (1 шт):
В качестве одного из решений можно передавать дополнительным параметром в функцию, создающую дерево, значение по умолчанию, должно быть оно раскрыто или закрыто.
Для этого можно применить параметры по умолчанию:
function generateTree(root, defaultExpanded = true) {
далее в коде, просто присвоить это значение:
var ul = document.createElement('ul');
ul.hidden = defaultCollapsed;
Дальше при первом вызове передаем параметр false, чтобы было видно дерево самого верхнего уровня.
generateTree(document, false);
Так как далее в коде этот метод вызывается без второго параметра, будет использовано значение по умолчанию (true) и все создаваемые поддеревья будут скрыты.
function generateTree(root, defaultCollapsed = true) {
if (root.childNodes.length == 0) return;
var ul = document.createElement('ul');
ul.hidden = defaultCollapsed;
return Array.from(root.childNodes).reduce((list, cur) => {
var li = document.createElement('li');
li.innerText = getTitleFromNode(cur);
if (cur.nodeType == Node.ELEMENT_NODE) {
var children = generateTree(cur);
if (children) {
li.appendChild(children);
}
}
list.appendChild(li);
return list;
}, ul)
}
function createTree(tree) {
var treeLis = tree.getElementsByTagName('li');
/* wrap all textNodes into spans */
for (var i = 0; treeLis.length > i; i++) {
var li = treeLis[i];
var span = document.createElement('span');
li.insertBefore(span, li.firstChild);
span.appendChild(span.nextSibling);
}
tree.onclick = function(event) {
var target = event.target;
if (target.tagName != 'SPAN') {
return;
}
var childrenContainer = target.parentNode.getElementsByTagName('ul')[0];
if (!childrenContainer) return; // no children
childrenContainer.hidden = !childrenContainer.hidden;
}
}
function getTitleFromNode(node) {
switch (node.nodeType) {
case Node.ELEMENT_NODE:
return node.tagName;
case Node.TEXT_NODE:
return node.nodeValue;
case Node.COMMENT_NODE:
return `<!--${node.textContent}-->`;
case Node.DOCUMENT_TYPE_NODE:
return `<!DOCTYPE ${node.name}>`;
default:
return node.toString();
}
}
var t = generateTree(document, false);
document.body.appendChild(t);
createTree(t);
.tree span:hover {
font-weight: bold;
}
.tree span {
cursor: pointer;
}
text
<!-- COMMENT -->
<div>1<span>33</span>2</div>