Компактное дерево
Добрый день!
есть скрипт древовидного меню: <style> p { margin: 0px } body { font-size: 11px; font-family: verdana; line-height: 17px } .sub { padding-left: 20px; display: block } .menu { cursor: pointer; display: block } a { text-decoration: none; color: #000000 } </style> <script language=JavaScript> function show(obj) { if (document.getElementById(obj).style.display == 'none') document.getElementById(obj).style.display = 'block'; else document.getElementById(obj).style.display = 'none'; } </script> <span class="menu" onclick="show('sub1')">+ Статьи</span> <span class="sub" id="sub1" style="display: none"> <p><a href='http://'>Интернет</a></p> <p><a href='http://'>JavaScript</a></p> </span> <span class="menu" onclick="show('sub2')">+ Рейтинг</span> <span class="sub" id="sub2" style="display: none"> <p><a href='http://'>Главная</a></p> <p><a href='http://'>Регистрация</a></p> <p><a href='http://'>Статистика</a></p> </span> <span class="menu" onclick="show('sub3')">+ Форум</span> <span class="sub" id="sub3" style="display: none; border: 3px"> <p><a href='http://www.webobzor.net'>Регистрация</a></p> <p><a href='http://www.webobzor.net'>Cообщения</a></p> <p><a href='http://www.webobzor.net'>Поиск</a></p> </span> Как сделать что бы при открытии ветки меню, остальные ранее открытые ветки закрывались? Спасибо! |
в show находишь все span'ы с классом sub и скрываешь все, кроме того, который показываешь
|
Цитата:
|
видимо, пользоваться поиском по форуму не учили:
function getElementsByClass(searchClass,node,tag) { //Dustin Diaz's getElementsByClass implementation var classElements = new Array(); if ( node == null ) node = document; if ( tag == null ) tag = '*'; var els = node.getElementsByTagName(tag); var elsLen = els.length; var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)"); for (i = 0, j = 0; i < elsLen; i++) { if ( pattern.test(els[i].className) ) { classElements[j] = els[i]; j++; } //if } //for return classElements; } if(document.getElementsByClassName) { var anal_tables = document.getElementsByClassName("sub"); //Firefox 3 C++ native implementation } else { var anal_tables = getElementsByClass("sub", document, "span"); //Dustin Diaz's getElementsByClass implementation } |
чего то я не догоню никак, как теперь скрыть то :help:
пытался сделать document.getElementByClassname("sub").style.display = 'none'; но ничего не получается |
getElementByClassname возвращают коллекцию объектов, а не один объект.
а getElementsByClass возвращает массив.но не один объект обращайтесь к конкретному элементу по индексу. либо перебирайте в цикле все элементы |
ай опередил меня :)
|
Спасибо всем за помощь!
Сделал сам :dance: только по другому: function show(obj) { if (document.getElementById(obj).style.display == 'none') { if(typeof old == "undefined") { old=""; } else { document.getElementById(old).style.display = 'none'; } document.getElementById(obj).style.display = 'block'; old=obj; return (old); } else document.getElementById(obj).style.display = 'none'; } |
если честно - не красиво...
|
Цитата:
function show(obj) { if (document.getElementById(obj).style.display == 'none') { if(typeof old != "undefined") { document.getElementById(old).style.display = 'none'; } document.getElementById(obj).style.display = 'block'; old=obj; return (old); } else document.getElementById(obj).style.display = 'none'; } |
я бы сделал как-то так:
<style> p { margin: 0px } body { font-size: 11px; font-family: verdana; line-height: 17px } .sub { padding-left: 20px; display: block } .menu { cursor: pointer; display: block } a { text-decoration: none; color: #000000 } </style> <script language=JavaScript> function show( node ) { if( arguments.callee.prv ) arguments.callee.prv.style.display = 'none'; do { node = node.nextSibling; } while (! node.tagName); arguments.callee.prv = node; node.style.display = 'block'; } </script> <span class="menu" onclick="show(this)">+ Статьи</span> <span class="sub" id="sub1" style="display: none"> <p><a href='http://'>Интернет</a></p> <p><a href='http://'>JavaScript</a></p> </span> <span class="menu" onclick="show(this)">+ Рейтинг</span> <span class="sub" id="sub2" style="display: none"> <p><a href='http://'>Главная</a></p> <p><a href='http://'>Регистрация</a></p> <p><a href='http://'>Статистика</a></p> </span> <span class="menu" onclick="show(this)">+ Форум</span> <span class="sub" id="sub3" style="display: none; border: 3px"> <p><a href='http://www.webobzor.net'>Регистрация</a></p> <p><a href='http://www.webobzor.net'>Cообщения</a></p> <p><a href='http://www.webobzor.net'>Поиск</a></p> </span> 1) нету глобальной переменной, 2) не нужно задавать id для всех подменю и привязывать обработчики к своим подменю - функция show сама все находит |
Вот блин! Потребовалось сделать компактное дерево с неограниченным количеством уровней
<style> p { margin: 0px } body { font-size: 11px; font-family: verdana; line-height: 17px } .sub { padding-left: 20px; display: block } .menu { cursor: pointer; display: block } a { text-decoration: none; color: #000000 } </style> <script language=JavaScript> function show(obj) { if (document.getElementById(obj).style.display == 'none') { if (typeof old != "undefined") { document.getElementById(old).style.display = 'none'; } document.getElementById(obj).style.display = 'block'; old=obj; return (old); } else document.getElementById(obj).style.display = 'none'; } </script> <span class="menu" onclick="show('sub1')">+ Статьи</span> <span class="sub" id="sub1" style="display: none"> <p><a href='http://'>Интернет</a></p> <p><a href='http://'>JavaScript</a></p> </span> <span class="menu" onclick="show('sub2')">+ Рейтинг</span> <span class="sub" id="sub2" style="display: none"> <p><a href='http://'>Главная</a></p> <p><a href='http://'>Регистрация</a></p> <p><a href='http://'>Статистика</a></p> </span> <span class="menu" onclick="show('sub3')">+ Форум</span> <span class="sub" id="sub3" style="display: none; border: 3px"> <a href='http://'>Регистрация</a></p> <span class="menu" onclick="show('sub4')">+ Cообщения</span> <span class="sub" id="sub4" style="display: none"> <p><a href='http://'>Главная</a></p> <p><a href='http://'>Регистрация</a></p> <p><a href='http://'>Статистика</a></p> </span> <p><a href='http://'>Поиск</a></p> </span> И чего то я застрял, возникла идея вызывать функцию show, в которой будет указан еще и уровень вложения, например: ... onclick="show('sub4','2')" .... а как это применить не соображу :help: |
зачем тебе уровень передавать? Оно и так должно работать. Просто есть разные варианты реализации... чем тебя твой не устраивает? Ну или вообще, как ты представляешь работу многоуровневого меню?
|
Цитата:
<style> p { margin: 0px } body { font-size: 11px; font-family: verdana; line-height: 17px } .sub { padding-left: 20px; display: block } .menu { cursor: pointer; display: block } a { text-decoration: none; color: #000000 } </style> <script language=JavaScript> old = new Array(10); function show(obj,level) { if (document.getElementById(obj).style.display == 'none') { if ((typeof last != "undefined")&&(lastlevel != "undefined")) { if (level<lastlevel) { for (var n=level; n<=lastlevel; n++) { document.getElementById(old[n]).style.display = 'none'; } } if (lastlevel==level) { document.getElementById(last).style.display = 'none'; } } document.getElementById(obj).style.display = 'block'; last=obj; old[level]=obj; lastlevel=level; return (last,lastlevel,old); } else document.getElementById(obj).style.display = 'none'; } </script> <span class="menu" onclick="show('sub1','1')">+ 1</span> <span class="sub" id="sub1" style="display: none"> <p><a href='http://'>1.1</a></p> <p><a href='http://'>1.2</a></p> </span> <span class="menu" onclick="show('sub2','1')">+ 2</span> <span class="sub" id="sub2" style="display: none"> <p><a href='http://'>2.1</a></p> <p><a href='http://'>2.2</a></p> <p><a href='http://'>2.3</a></p> </span> <span class="menu" onclick="show('sub3','1')">+ 3</span> <span class="sub" id="sub3" style="display: none; border: 3px"> <a href='http://'>3.1</a></p> <span class="menu" onclick="show('sub4','2')">+ 3.2</span> <span class="sub" id="sub4" style="display: none"> <p><a href='http://'>3.2.1</a></p> <span class="menu" onclick="show('sub6','3')">+ 3.2.2</span> <span class="sub" id="sub6" style="display: none"> <p><a href='http://'>3.2.2.1</a></p> <p><a href='http://'>3.2.2.2</a></p> <p><a href='http://'>3.2.2.3</a></p> </span> <p><a href='http://'>3.2.3</a></p> <p><a href='http://'>3.2.4</a></p> </span> <span class="menu" onclick="show('sub5','2')">+ 3.3</span> <span class="sub" id="sub5" style="display: none"> <p><a href='http://'>3.3.1</a></p> <p><a href='http://'>3.3.2</a></p> <p><a href='http://'>3.3.3</a></p> </span> <p><a href='http://'>3.4</a></p> </span> Сделал, только остался вопрос. Почему не желательно использовать глобальные переменные? |
потому что это может приводить к неожиданным багам, которые может быть нелегко найти. Потому что разные части кода могут непреднаеренно использовать одну и ту же переменную, и если это происходит одновременно...
Крайний случай: ключевое слово var всячески игнорируется - т.е. все переменные глобальные p.s. и чем больше скриптов на странице (учитывая внешние библиотеки, если такие есть) - тем это актуальнее |
Цитата:
1) имена переменных придумывать позакавырестее 2) или cкрывать все элемены меню, с помощью функции getElementByClass, искать все родительские ветки и делать им style.display = 'block' ? |
проблемы возникнут в том, что у вас переменная может называться content и в каком-то скрипте может существовать такая-же переменная. и результаты того, что участки кода, использующие эти переменные, могут выполняться одновременно - вы можете представить сами.
пойдем от обратного. Цитата:
Цитата:
пример. a=5; for (i=0;i<5;i++) {alert (a);} пять раз выведется 5 a=5; for (i=0;i<5;i++) {var a=4; alert (a);} alert(a); пять раз выведется 4, а потом выведется 5. понятно? |
С глобальными переменными все ясно!
Спасибо всем за помощь! |
AzriMan, неудачный пример, 6 раз выведется 4. Лучше что-то типа
function a() { for( i=0; i<2; i++ ) b(); } function b() { for( i=0; i<2; i++ ) alert('b'); } a(); |
x-yuri, хм, да, действительно. а почему?
|
Потому что i, в данном случае, глобальная.
|
хм. такой пример:
<html><head> <script type="text/javascript"> var a=5; for (var i=0;i<5;i++) {var a=4; alert (''+a+i);} alert('!'+a+i); </script> </head><body></body></html> i, теоретически, должна быть видима в пределах цикла. но последним выводом будет "!45". все равно не пойму.. |
Цитата:
|
Цитата:
но, я думаю, всё встало на свои места. раз i в этом случае глобальная, следовательно var a, созданный в цикле, тоже будет глобальным. следовательно, созданный ранее var a=5; будет затерт ноым глобальным значением. вот и ответ. буду знать, что в JS, все-таки, есть некие отличия от C/C++ в области видимости. спасибо. |
потому что есть 3 типа исполняемого кода: глобальный, функция и eval. Объявление переменных происходит перед выполнением, а присваивание - во время и не важно, что переменная объявлена в for:
alert(a); // если бы не было var a, то здесь бы выполнение прекратилось - ошибка for( var i=0; i<1; i++ ) { var a=4; // значение присваивается здесь } alert(a); вроде так |
Цитата:
|
Часовой пояс GMT +3, время: 10:12. |