Re: Как сделать дерево
От: pattern Россия www.gho.ru
Дата: 29.12.06 09:53
Оценка:
Здравствуйте, Nico, Вы писали:

N>Проблема такова. Я сделал что-то подобное с помощью тэга <LI> только неполучается его вывести в свернутом виде. Вот и все.


Я всегда использую более простой способ. При генерации php-страницы я вывожу полное дерево в том виде, в котором оно должно быть при полном открытии. Каждой ветке выделяется отдельный слой (div). Сгенерировать такое дерево как 2 пальца об асфальт, главное не ограничивать себя в фантазиях. Вот примерно как должен быть выведен html-исходник.

<div><a href="#" onClick="showHideLayers('id_1')"><img src="plus.gif" /></a>Ветка 1</div>
  <div class="thread" id="id_1" style="display=none;">
    <div>Пункт 1.1</div>
    <div>Пункт 1.2</div>
  </div>
<div><a href="#" onClick="showHideLayers('id_2')"><img src="plus.gif" /></a>Ветка 2</div>
  <div class="thread" id="id_2">
    <div><a href="#" onClick="showHideLayers('id_21')"><img src="plus.gif" /></a>Ветка 2.1
      <div class="thread" id="id_21">
        <div>Пункт 2.1.1</div>
        <div>Пункт 2.1.2</div>
        <div>Пункт 2.1.3</div>
      </div>
    </div>
    <div><a href="#" onClick="showHideLayers('id_22')"><img src="plus.gif" /></a>Ветка 2.2
      <div class="thread" id="id_22" style="display=none;">
        <div>Пункт 2.2.1</div>
        <div>Пункт 2.2.2</div>
        <div>Пункт 2.2.3</div>
      </div>
    </div>
  </div>
<div><a href="#" onClick="showHideLayers('id_3')"><img src="plus.gif" /></a>Ветка 3</div>
  <div class="thread" id="id_3" style="display=none;">
    <div>Пункт 3.1</div>
    <div>Пункт 3.2</div>
  </div>
</div>


Чтобы не использовать всякие пункты (ul, ol, li), а потом в css-ах править где какой пункт показывать, а где не показывать, я использую css-класс thread, который содержит в себе следующее:

.thread
{
  width: 95%;
  float: right;
  text-align: left;
}


Таким образом, с помощью width можно регулировать глубину отступа от левого края дерева. В итоге дерево получается на подобии вида дерева Explorer'а.
В зависимости от того, какую ветку выбрал пользователь, этот слой устанавливается через css в положение visible, остальные hide. В привидённом выше примере открыта Ветка 2 с подветкой 2.1, остальные все скрыты. Ну а в конечном сгенерированном html-коде начинает уже работать JavaScript:

function findObj(theObj, theDoc)
{
  var p, i, foundObj;
  if(!theDoc) theDoc = document;
  if( (p = theObj.indexOf("?")) > 0 && parent.frames.length)
  {
    theDoc = parent.frames[theObj.substring(p+1)].document;
    theObj = theObj.substring(0,p);
  }
  if(!(foundObj = theDoc[theObj]) && theDoc.all) foundObj = theDoc.all[theObj];
  for (i=0; !foundObj && i < theDoc.forms.length; i++)
    foundObj = theDoc.forms[i][theObj];
  for(i=0; !foundObj && theDoc.layers && i < theDoc.layers.length; i++)
    foundObj = findObj(theObj,theDoc.layers[i].document);
  if(!foundObj && document.getElementById) foundObj = document.getElementById(theObj);
  return foundObj;
}

function showHideLayers()
{
  var i,l_obj,visStr,obj=showHideLayers.arguments;
  for(i=0;i<(obj.length);i++)
  {
    if((l_obj=findObj(obj[i]))!=null)
    {
      if(l_obj.style)
      {
        l_obj=l_obj.style;
        if(l_obj.display=='none') visStr='';
        else if(l_obj.display=='') visStr='none';
      }
      l_obj.display=visStr;
    }
  }
}


Таким образом нажимая на gif-"плюсик" ветки 1 скрывается или открывается слой с id="id_1" и т.д. Каждый пункт и ветку можно залинковать на нужную страницу или так же на открытие любой ветки. Однако это не полный код. Требуется учесть, чтобы браузер "помнил", какие ветки были открыты пользователем, а какие скрыты при переходе со страницы на страницу. Однако это вариации на тему php о сохранении настроек пользователя и объяснять я их не буду, ибо вариантов масса.
Так же можно ещё добавить JavaScript смены картинки plus.gif на minus.gif, но это уже выходит за рамки данного объяснения.
Замечание по приведённому коду только одно: работает он во всех браузерах, которые мне попадались во время тестирования, умеющие работать с JavaScript. Однако такие браузеры как Opera и Firefox при начальной загрузке не отрабатывают скрытие слоя и потому всё дерево выводится открытым, что даёт небольшой дискомфорт при больших разветвлениях (во всяком случае так было, последние версии не тестировал).
Удачи!
---
Your bunny wrote: its not a bug, this is a feature, actually... ;)
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.