Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   Show/hide content (https://javascript.ru/forum/events/12240-show-hide-content.html)

dakath 08.10.2010 13:45

Show/hide content
 
Здравствуйте.

Есть php парсер, который вытаскивает инфу с xml файла, инфы так много что хочется скрыть контент и открывать по клику.

Варианты скрипта с разными id к сожалению не подходят.

Буду благодарен за любую помощь.

MikhailGirshberg 08.10.2010 14:05

вставьте в DOM первую "порцию" и кнопочку "продолжение следует".

По кнопочке (кнопочкам) с помощью AJAX организуйте листание "порций".

Вот здесь немного не о том, но близко по смыслу.

dakath 08.10.2010 14:13

MikhailGirshberg,
Спасибо за ответ, но хотел добиться не совсем этого, хочется сделать так:
После того как парсер отработает, нужно чтоб было видно имя элемента, имя атрибута и чтоб значение атрибута показывалось по клику.

MikhailGirshberg 08.10.2010 14:35

Цитата:

Сообщение от dakath (Сообщение 73504)
MikhailGirshberg,
чтоб значение атрибута показывалось по клику.

1. С помощью регулярных выражений содержимое двойных кавычек после знака равенства "заворачивается" в div.
2. в css определить 2 класса для div'а: один с display:none (он же по умолчанию), другой - с display:inline.
3. по клику эти классы должны меняться один на другой.
4. Перед вываливанием xml-дерева на страничку не забудьте htmlspecialchars

dakath 08.10.2010 14:51

MikhailGirshberg,
Если для Вас не составит труда, то был бы благодарен за рабочий пример.

MikhailGirshberg 08.10.2010 15:36

dakath,
С удовольствием, но не прямо сейчас... Рабочий день ещё не кончился.

dakath 08.10.2010 15:38

MikhailGirshberg,
Конечно, я подожду, спасибо.

MikhailGirshberg 09.10.2010 15:11

ну вот, не прошло и суток...
 
... как я снова здесь.

Пример строит дерево (предположительно, иллюстрирующее структуру 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), добавив аналогичную проверку для родительского элемента. В примере эта доппроверка исключена. Дабы не загромождать код.

MikhailGirshberg 11.10.2010 01:53

так, вроде, правильнее будет.
 
Функция applay_tree имитирует работу парсера по созданию иерархического списка, отражающего структуру документа.

Функция attr_transform скрывает значения аттрибутов и "стилизует" сам список. Предполагается, что из-под пасера список выходит "голым".

<!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">
      /*свойства списка*/
      li.taglist{
        list-style: none;
      }
      /*свойства блоков*/
      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>'
              var s = ' ' + i + '="' + tree[i] + '"'
              // имя="значение", причём значение - в отдельном блоке
              li.innerHTML += s // добавляем в элемент
          }
        }
        li.appendChild(ul)  // здесь в объект-элемент вставляется кенгурятник со всем содержимым (если оно есть)
        return li // возврат элемента позволит вставить его в "более высокоуровневые кенгурятники"
      }

      function attr_transform(node){  //  собственно, преобразование списка
        node.parentNode.removeChild(node) // убираем кнопку за ненадобностью
        var cont = document.getElementById('textcont')  // находим рамочный блок
        // следующие 2 строчки - скрываем значения аттрибутов и убираем символы списков
        cont.innerHTML = cont.innerHTML.replace(/(\w*=")([^"]*)"/gi,'<div class="named_attr">$1<div class="hidden">$2</div>"</div>')
        cont.innerHTML = cont.innerHTML.replace(/<li\s*>/gi, '<li class="taglist">')
      }
            
      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><!--рамочка в документе-->
    <input type="button" onclick="attr_transform(this)" value="свернуть аттрибуты"/>
  </body>
</html>


Часовой пояс GMT +3, время: 13:20.