Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 19.09.2009, 07:28
Аватар для Paguo-86PK
Профессор
Отправить личное сообщение для Paguo-86PK Посмотреть профиль Найти все сообщения от Paguo-86PK
 
Регистрация: 16.09.2009
Сообщений: 253

Сканирование вложенных списков
Необходимо просканировать следующее меню:
<menu mode="hor" value="Main">
 <menu class=0 mode="ver" title="Файл" value="File">
  <li mode="button" action="window.status='New'" title="Новый" value="New"/>
  <li mode="button" action="window.status='Open'" title="Открыть" value="Open"/>
  <li mode="button" action="window.status='Save'" title="Сохранить" value="Save"/>
  <li mode="button" action="window.status='Close'" title="Закрыть" value="Open"/>
  <li mode="separator"/>
  <li mode="button" action="window.status='Exit'" title="Выйти" value="Exit"/>
 </menu>
 <menu class=0 mode="ver" title="Правка" value="Edit">
  <li mode="button" action="window.status='Cut'" title="Вырезать" image="cut.gif" value="Cut"/>
  <li mode="button" action="window.status='Copy'" title="Копировать" image="copy.gif" value="Copy"/>
  <li mode="button" action="window.status='Paste'" title="Вставить" image="paste.gif" value="Paste"/>
 </menu>
 <menu class=0 mode="ver" title="Вид" value="View">
  <menu class=0 mode="hor" value="Syntax" title="Синтаксис">
   <li mode="button" action="window.status='Asm'" title="Ассемблер" value="Assembler"/>
   <li mode="button" action="window.status='Basic'" title="Бейсик" value="Basic"/>
   <li mode="button" action="window.status='Cpp'" title="Си" value="C++"/>
  </menu>
  <menu class=0 mode="hor" title="Переключатели" value="Triggers">
   <li mode="radio" action="window.status='Radio 1'" title="Опция #1" value="Radio 1"/>
   <li mode="radio" action="window.status='Radio 2'" title="Опция #2" value="Radio 2"/>
   <li mode="radio" action="window.status='Radio 3'" title="Опция #3" value="Radio 3"/>
   <li mode="separator"/>
   <li mode="check" action="window.status='Check 1'" title="Флажок #1" value="Check 1"/>
   <li mode="check" action="window.status='Check 2'" title="Флажок #2" value="Check 2"/>
   <li mode="check" action="window.status='Check 3'" title="Флажок #3" value="Check 3"/>
  </menu>
 </menu>
 <li mode="button" value="Help" action="window.status='Help'" title="Справка"/>
</menu>
Написал рекурсивную функцию, которая должна пробегать по всем элементам с произвольной вложенностью. Однако, спотыкаюсь на одном месте:
Почему-то в рекурсии функция не обрабатывает дочерные ноды, а сканирует с начала.

Вот примерный алгоритм:
var ii=0; // Отладочный счётчик глубины рекурсии
function CreateMenu(items) {
 var i, s;
 var mnu = new Array(); // Копим элементы меню здесь
 ++ii;
 for(i = 0; i < items.length; ++ i) {
  itm = items[i];
  document.getElementById("pres").innerHTML += ii + ' type=' + itm.mode + ' value=' + itm.value + ', ' + itm.tagName + '<br/>'; // pres - <pre id='pres'>Debug log</pre>
  switch(itm.mode) {
  case "hor":
  document.getElementById("pres").innerHTML += 'hor<br>';
   mnu[mnu.length] = itm.value + " " + itm.title + " >";
   mnu[mnu.length] = CreateMenu(items.getChildElements()); // Тут и ошибка! Нужно из <menu> извлечь вложенные пункты меню <li> или подменю <menu>...
   break;
  case "ver":
  document.getElementById("pres").innerHTML += 'ver<br>';
   mnu[mnu.length] = itm.value + " " + itm.title + " v";
   mnu[mnu.length] = CreateMenu(itm.getElementsByTagName("LI"));
   break;
  case "button":
  document.getElementById("pres").innerHTML += 'button<br>';
   mnu[mnu.length] = itm.value + " " + itm.title + " " + itm.action + "" + "";
   break;
  case "radio":
   mnu[mnu.length] = itm.value + " " + itm.title + " " + itm.action + "" + ";";
   break;
  case "separator":
   mnu[mnu.length] = "";
   break;
  }
 }
 mnu[mnu.length] = ".";
 --ii;
 return mnu;
}
function CreateMnu(items) {
 return CreateMenu(items[0].getElementsByTagName("MENU"));
}
window.onload = function() {
mnu = document.getElementsByTagName("MENU");
 mnus = CreateMnu(mnu);
 document.body.removeChild(mnu[0]);
...
Функция визуализации меню имеется собственной давней разработки. Работает отлично, но формирует меню из Array. Проблема лишь в том, что не могу верно обработать <menu>, которое, затем просто удаляется со страницы как пережиток прошлого... Оно лишь нужно, чтобы сгенерировать Array... Так-как JS генерации меню работает в фоне без лишних вызовов...

Спасибо!
Ответить с цитированием
  #2 (permalink)  
Старый 19.09.2009, 18:43
Аватар для x-yuri
Отправить личное сообщение для x-yuri Посмотреть профиль Найти все сообщения от x-yuri
 
Регистрация: 27.12.2008
Сообщений: 4,201

а сразу этот Array использовать нельзя? Что такое getChildElements? Ошибки в консоли какие-то появляются?
Ответить с цитированием
  #3 (permalink)  
Старый 20.09.2009, 00:20
Аватар для Paguo-86PK
Профессор
Отправить личное сообщение для Paguo-86PK Посмотреть профиль Найти все сообщения от Paguo-86PK
 
Регистрация: 16.09.2009
Сообщений: 253

Разобрался за несколько часов. Я забыл, что вместо getChildElements существует all[]...
В общем, 15 минут назад лишь добился генерации меню работающего.
Однако, смущает следующее:
function CreateMenu(items) {
 var i, s;
 var mnu = new Array();
 for(i = 0; i < items.length; ++ i) {
  itm = items[i];
  switch(itm.mode) {
  case "menu":
   mnu[mnu.length] = itm.caption;
   i += (mnus = CreateMenu(itm.all)).length - 1; // <-- Вот тут указатель i обязательно нужно сместить, чтобы снова не читать те же элементы
   for(j in mnus)                                // <-- А здесь необходимо искусственно сделать concat
    mnu[mnu.length] = mnus[j];
   break;
  case "button":
   mnu[mnu.length] = itm.caption + " " + itm.title + " " + itm.action + " " + " " + (itm.image ? itm.image : "");
   break;
...
  case "separator":
   mnu[mnu.length] = "";
   break;
  }
 }
 mnu[mnu.length] = ".";
 return mnu;
}
т.е. необходимо смещать указатель так, чтобы обойти дочерние элементы дочерного элемента. Как это обойти? Удалать дочерний элемент на лету вместе с его содержимым? Кривовато и не красиво

Последний раз редактировалось Paguo-86PK, 20.09.2009 в 00:23.
Ответить с цитированием
  #4 (permalink)  
Старый 20.09.2009, 16:53
Аватар для Riim
Рассеянный профессор
Отправить личное сообщение для Riim Посмотреть профиль Найти все сообщения от Riim
 
Регистрация: 06.04.2009
Сообщений: 2,379

all[] работает только в IE и Opera.
Ответить с цитированием
  #5 (permalink)  
Старый 21.09.2009, 10:38
Аватар для B~Vladi
Модератор Всея Форума
Отправить личное сообщение для B~Vladi Посмотреть профиль Найти все сообщения от B~Vladi
 
Регистрация: 14.05.2009
Сообщений: 4,021

Сообщение от Paguo-86PK
вместо getChildElements существует all[]
вместо getChildElements существует childNodes.
Ответить с цитированием
  #6 (permalink)  
Старый 24.09.2009, 03:48
Аватар для Paguo-86PK
Профессор
Отправить личное сообщение для Paguo-86PK Посмотреть профиль Найти все сообщения от Paguo-86PK
 
Регистрация: 16.09.2009
Сообщений: 253

childNodes? Странно, но заменив все, вернее всего два, all на childNodes, у меня меню испортилось: Многие пункты повылазали из подменю в основное...
Ответить с цитированием
  #7 (permalink)  
Старый 24.09.2009, 04:14
Отправить личное сообщение для Octane Посмотреть профиль Найти все сообщения от Octane  
Регистрация: 10.07.2008
Сообщений: 3,873

Потомучто childNodes не аналочино all работает, в возвращаемую коллекцию попадают все узлы, в том числе и текстовые, нужно дополнительно проверять nodeType == 1.
Ответить с цитированием
  #8 (permalink)  
Старый 24.09.2009, 04:41
Аватар для Paguo-86PK
Профессор
Отправить личное сообщение для Paguo-86PK Посмотреть профиль Найти все сообщения от Paguo-86PK
 
Регистрация: 16.09.2009
Сообщений: 253

Всё сломалось и не лечится...
Завтра буду ковыряться
Ответить с цитированием
  #9 (permalink)  
Старый 24.09.2009, 10:37
Аватар для B~Vladi
Модератор Всея Форума
Отправить личное сообщение для B~Vladi Посмотреть профиль Найти все сообщения от B~Vladi
 
Регистрация: 14.05.2009
Сообщений: 4,021

Сообщение от Paguo-86PK
Всё сломалось и не лечится...
Чего радуешься
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Каскад динамических списков ..::Silence::.. AJAX и COMET 10 22.01.2010 08:35
Нужен тулкит для сортировки списков cj_spotty Элементы интерфейса 7 31.07.2009 09:27
Как сделать чтобы text() брал только текст родителя без текста вложенных контейнеров? Andrey32 jQuery 3 23.05.2009 01:33