Kamrad.ru (https://kamrad.ru/index.php)
- Веб-дизайн, вёрстка и веб-программирование (https://kamrad.ru/forumdisplay.php?forumid=87)
-- Выпадающее меню (https://kamrad.ru/showthread.php?threadid=60851)
Выпадающее меню
Столкнулся тут с такой проблемой: есть у меня кнопка при наведении на которою появляется новый слой (это меню)
Как сделать так, чтобы этот слой не "уезжал" при изменении размеров окна, а оставался точно под кнопкой?
__________________
Obi-Wan
Obi-Wan
IE: делать position:absolute и назначать координаты точно под кнопкой.
Координаты рассчитываются циклом, суммированием offsetTop и offsetLeft для кнопки и всех ее offsetParent, до тех пор, пока offsetParent станет не NULL либо не будет иметь тэг BODY.
Anafay
Так и сделано вобщем смотри сам
Obi-Wan
Посмотрел. Y-координата выставляется, а X - нет. Выставляй не только top, но и left - и все поедет
Иначе при ресайзе окна у тебя кнопки смещаются, а выпадающие меню остаются на прежнем месте.
Далее, если не хочешь проблем, то не вставляй без особой нужды элементы position:absolute внутри элементов с относительным позиционированием (как у тебя они внутри <p> ). Только сразу в body.
Как это не выставляется? Смотри кусок кода:
"<div id=box style="position:absolute; left:239px; Z-INDEX:100; top:36px; visibility: visible;">
<table border="0" id=blackbox width="80">
<tr><td bgcolor="#FFFFFF"><a href='!!!!!!' >Link</a></td></tr>
<tr><td bgcolor="#FFFFFF"><a href='!!!!!!' >Link</a></td></tr>
</table>
</div>"
Obi-Wan
Смотри другой кусок кода:
<table width=720 align="center" cellpadding=0 cellspacing=0 class="cheader3">
Кнопки меняют свое положение в зависимости от ширины документа, а эти div'ы - нет:
showBox = document.all.box[x];
showBox.style.visibility = "visible";
showBox.style.top = 20;
// Сюда надо добавить установку showBox.style.pixelLeft, рассчитанную циклом через offsetLeft
Anafay
Подскажи какую установку надо добавить а то я не очень секу в этом.
Obi-Wan
Передавай в функцию саму кнопку (еще один аргумент this), а координату рассчитай с помощью вот этой функции (не проверял, писал сходу, и только IE):
code:
function leftPos(obj)
// Определение абсолютной левой координаты
{
var o=obj; // Счетчик для прохода по иерархии
var x=0; // Для суммирования координат
for(;o && String(o.tagName).toLowerCase()!='body';o=o.offsetParent)
x+=Number(o.offsetLeft);
return x;
}
Anafay
Напиши пожалуйста, мне спешить некуда...
Попробовал тут DHTMl Menu Builder - фууууууууу мне своё дороже чем шаблоны....
Держи.
code:
function initSubmenu(id,objName,classID)
// Конструктор выпадающего меню
{
this.ID=String(id); // ID div'а с меню
this.objName=String(objName); // Имя переменной с меню
this.classID=String(classID); // Класс div'а или пусто
/*
** Пункты меню
*/
this.count=0; // Количество пунктов меню
this.capacity=20; // Максимальное число пунктов меню
this.texts=new Array(this.capacity); // Тексты (или HTML-код) пунктов меню
this.urls=new Array(this.capacity); // URL/URI пунктов меню
this.titles=new Array(this.capacity); // Тексты подсказок пунктов меню
this.add=function(txt,url,title)
{
if(this.count>=this.capacity) return;
this.texts[this.count]=txt;
this.titles[this.count]=title;
this.urls[this.count++]=url;
} // Добавление нового пункта в конец списка
this.drawItems=function(doc)
{
var i;
for(i=0;i<this.count;i++)
doc.writeln('<A href="'
, this.urls[ i]
, '" title="'
, this.titles[ i]
, '">'
, this.texts[ i]
, '</A>');
} // Вывод пунктов меню в doc
/*
** Позициониорвание
*/
this.isVisible=function()
{
return (('visible'==String(document.all(this.ID).style.visibility
).toLowerCase())?(1):(0));
} // DIV виден
this.hide=function()
{
document.all(this.ID).style.visibility="hidden";
this.stopMouseTracking();
this.mouseInMenu=0;
if(0!=this.mouseTimeout)
{
window.clearTimeout(this.mouseTimeout);
this.mouseTimeout=0;
}
} // Удаление
this.moveTo=function(x,y)
{
document.all(this.ID).style.pixelLeft=x;
document.all(this.ID).style.pixelTop=y;
document.all(this.ID).style.visibility="visible";
} // Перевод div'а в нужную позицию и его показ
this.moveUnder=function(obj)
{
var x=0,y=0; // Координаты для позиционирования подменю
var o; // Счетчик родителей
for(o=obj;!0 && 'body'!=String(o.tagName).toLowerCase();o=o.offsetParent)
{
x+=Number(o.offsetLeft);
y+=Number(o.offsetTop);
}
y+=Number(obj.offsetHeight);
this.moveTo(x+1,y+1);
} // Установка DIV'а непосредственно под
/*
** Слежение за мышью
*/
this.mouseTracking=0; // Флаг необходимости отслеживать мышь
this.mouseTimeout=0; // Таймер для удаления подменю
this.mouseInMenu=0; // Флаг наличия мыши в меню
this.stopMouseTracking=function()
{
this.mouseTracking=0;
} // Конец слежения за мышью
this.startMouseTracking=function()
{
this.mouseTracking=1;
if(0!=this.mouseTimeout)
{
window.clearTimeout(this.mouseTimeout);
this.mouseTimeout=0;
}
this.mouseTimeout=window.setTimeout(this.objName+'.hide();',1000);
} // Конец слежения за мышью
this.onMouseOver=function()
{
this.mouseInMenu=1;
if(0!=this.mouseTimeout)
{
window.clearTimeout(this.mouseTimeout);
this.mouseTimeout=0;
}
} // Иышь внутри div-а - удаление таймера
this.onMouseOut=function()
{
this.mouseInMenu=0;
if(0!=this.mouseTimeout)
{
window.clearTimeout(this.mouseTimeout);
this.mouseTimeout=0;
}
this.mouseTimeout=window.setTimeout(this.objName+'.hide();',1000);
} // Мышь за пределами подменю - выставляем таймер на уделение подменю
/*
** Вывод div'а
*/
this.initialize=function(doc)
{
doc.write ('<DIV id="'
, this.ID
, '" ');
if(''!=this.classID)
doc.write('class="',this.classID,'" ');
doc.writeln('onMouseOver="'
, this.objName
, '.onMouseOver();" onMouseOut="'
, this.objName
, '.onMouseOut();" style="position:absolute;visibility:hidden;">');
this.drawItems(doc);
doc.writeln('</DIV>');
} // Вывод HTML-кода DIV'а в документ
}
code:
var submenu1=new initSumbenu('submenu1','submenu1',''); // Создание собственно подменю
submenu1.add('Текст пункта','URI пункта','Title пункта'); // Добавление пункта подменю
submenu1.initialize(document); // Вывод HTML-кода
code:
<SCRIPT>
var submenu1=new initSumbenu('submenu1','submenu1',''); // Создание собственно подменю
</SCRIPT>
<DIV id=submenu1>
...
Anafay
Огромное тебе спасибо! очень полезный скрипт!
Даже я со своими скромными знаниями javasсript всего за 2 часа настроил этот скрипт под себя ПОЛНОСТЬЮ.
Только вот глючит он иногда - наводишь на кнопку(e меня меню появляется через onMouseOver) и появляется меню, но тутже, (через 1000) исчезает.
Нашёл тут серьезную ошибку...
Допустим у меня есть страница www.simple.ru/index.html а с неё выпадающим меню ссылки на www.simple.ru/cont/index.html и www.simple.ru/cont2/index.html
Тогда заходим через это меню на cont/index.html (Предполагается что там тоже есть такое же меню) С этой страницы пытаемся зайти на cont2/index.html
НО!
Появляется ошибка "www.simple.ru/cont/index.html/cont2/index.html was not..."
А причина вся в том, что скрипт открывает относительные ссылки вот здесь:
code:
submenu1.add('cont1','cont/index.html',''cont1); // Добавление пункта подменю
code:
var sitename = "http://www.simple.ru/"
this.urls[this.count++]=sitename + url;
Obi-Wan
Только вот глючит он иногда - наводишь на кнопку(e меня меню появляется через onMouseOver) и появляется меню, но тутже, (через 1000) исчезает.
Обработкой мыши над кнопкой скрипт не занимается. Так что, думаю, что это происходит, если мышь увести с кнопки, а потом поставить назад. Можно сделать по образу и подобию.
А причина вся в том, что скрипт открывает относительные ссылки вот здесь:
Никогда не используй относительные ссылки. Правильно: '/cont/index.html'
this.urls[this.count++]=sitename + url;
Так делать нежелательно. Поскольку это
1) Дает лишний DNS-resolve. И если DNS не кэшируется - то замедляет загрузку, что не есть гуд.
2) Не дает использовать Keep Connection Alive, что приводит к обязательному повтору медленной фазы TCP-соединения.
Просто указывай полный URI документа.
Текущее время: 15:38
Powered by: vBulletin Version 2.0.1
Copyright © Jelsoft Enterprises Limited 2000, 2001.
Любое использование материалов сайта
возможно только с разрешения его администрации.