... как я снова здесь.
Пример строит дерево (предположительно, иллюстрирующее структуру XML-документа) в виде вложенных списков как элементов DOM. Для каждого элемента показывается имя, вложенные поддеревья элементов и группы пара="значение" для остальных аттрибутов. По умолчанию, значения аттрибутов скрыты. Кликнув по имени, их можно раскрыть. Повторно кликнув - скрыть снова.
В примере я выпустил момент создания объекта (json), описывающего дерево XML. Полагаю, не Javascript-овое это дело, на серверной стороне гораздо удобнее парсить XML. В принципе, не вопрос всё преобразование спихнуть на серверную сторону.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>XML nodetree representation</title>
<style type="text/css">
/*свойства блоков*/
div.named_attr{border: 1px dotted silver;cursor:default;}/*бордюр и курсор - для красоты*/
div.named_attr,div.named_attr div{display: inline}/*оставим блоки в строке*/
div.named_attr div.hidden{display: none}/*скрыть "скрытое"*/
</style>
<script type="text/javascript">
// Здесь я задаю структуру и наполнение дерева объектом
// В реальной жизни что-то вроде этого выполнит парсер XML на серверной стороне
var tags_tree = {"name":"root", "theme":"a1", "subj":"b1", "category":"c1", "children":[
{"name":"child1", "class":"c1", "children":[
{"name":"grandchild1", "class":"c2", "children":[]}
]},
{"name":"child2", "class":"c1", "children":[
{"name":"grandchild2", "class":"c2", "children":[]},
{"name":"grandchild3", "class":"c2", "children":[]} // у всех объектов одинаковая структура
// name - имя объекта, children - массив объектов-детей, остальные поля - пары 'имя:значение'
]},
{"name":"child3", "class":"c1", "children":[]}
]}
function apply_tree(tree){ // отображаем дерево объектов(tree) в дерево элементов DOM
var li = document.createElement('LI') // элемент дерева станет элементом списка - так проще форматировать
li.className = "nodedesk" // у меня не используется. можно применять для изменения вида списка
var ul = document.createElement('UL') // "кенгурятник" для детей
for(var i in tree){ // полями объекта являются имя, список детей (вложенных объектов) и свободные поля
switch(i){
case 'name': // имя объекта
li.innerHTML += tree[i] // без затей добавляется в элемент (ещё НЕ DOM - просто объект-элемент)
break;
case 'children': // массив вложенных объектов (детей)
var subtree = tree[i] // каждый вложенный объект разбирается как (под)дерево и добавляется в
if(subtree.length > 0) for(var j in subtree)ul.appendChild(apply_tree(subtree[j]))// кенгурятник
break;
default: // прочие (свободные) поля
var s = ' <div class="named_attr">' // превращаются в блоки
s += i + '="' + '<div class="hidden">' + tree[i] + '</div>"</div>'
// имя="значение", причём значение - в отдельном блоке
li.innerHTML += s // добавляем в элемент
}
}
li.appendChild(ul) // здесь в объект-элемент вставляется кенгурятник со всем содержимым (если оно есть)
return li // возврат элемента позволит вставить его в "более высокоуровневые кенгурятники"
}
onload = function(){ // вызывается один раз - при загрузке документа
var textcont = document.getElementById('textcont') // место в документе, где будем строить список
var ul = document.createElement('UL') // корневой "супер-кенгурятник"...
ul.appendChild(apply_tree(tags_tree)) // ... вмещает корневой элемент со всем содержимым
textcont.appendChild(ul) // вставляем кенгурятник в рамочку, которая уже висит в документе
textcont.onclick = function(event){ // на ВСЮ рамочку вешаем обработчик события "клик мышкой"
event = event || window.event // несколько выморочным, но безотказно-кроссбраузерным способом...
var elem = event.target || event.srcElement // ... определяем, где кликнули
if(elem.className.search('named_attr')< 0) return // если не там - уходим
elem = elem.getElementsByTagName('DIV')[0] // в кликнутом элементе находим вложенный блок
if(elem.className.search('hidden') < 0) elem.className += 'hidden' // если открыт - закроем
else elem.className = elem.className.replace('hidden', "") // иначе - откроем
}
}
</script>
</head>
<body>
<div id="textcont"></div><!--рамочка в документе-->
</body>
</html>
Прошу сообщить, если не читаются комментарии в HTML-коде, возможны проблемы с кодировками.
Да, и ещё. Обрабатывается клик только на имя "аттибута", но не на значение. Чтобы это исправить, надо переработать проверку (стр. 59), добавив аналогичную проверку для родительского элемента. В примере эта доппроверка исключена. Дабы не загромождать код.