Компактное дерево
Добрый день!
есть скрипт древовидного меню:
<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, время: 00:07. |