Выпадающее меню

Сегодня, дети, я вам расскажу сказку про тётю Джаву.
Нет… это совсем другая история.

Речь пойдёт о выпадающем меню.Условия:

  1. должно работать во всех браузерах;
  2. наигибкость при динамическом создании меню в cms;
  3. настраиваемый внешний вид

Скрипт не претендует на звание наилучшего. Свои минусы тоже имеются.
Для примера было взято меню с Blender3D.

Начнём с простого. Создадим меню из ссылок:


<div id="ns_navigation">
<div></div>
<a href="about" onmouseover="ns_menushow(this, ‘Features=features| Gallery=gallery| Applications=applications| Testimonials=testimonials| Requirements=requirements’);" onmouseout="ns_menuhide(this);">About Blender</a>
<div></div>
<a href="news" onmouseover="ns_menushow(this, ‘Blender News=blender-news| Announcements=announcements| Development=development| Artists=artists|Submit News=submit-news’);" onmouseout="ns_menuhide(this);">News</a>
.............................................................
<a href="blender-foundation" onmouseover="ns_menushow(this, ‘About=about|Blender conference=blender -onference|History=history|Donation & payment=donation-n-payment|Press=press|Media Exposure=media-exposure’);" onmouseout="ns_menuhide(this);">Blender Foundation</a>
<div></div>
<a href="e-shop" onmouseover="ns_menushow(this, ‘Books=books|Downloadable=downloadable|CD Roms=cd-roms|Blender Wear=blender-wear’);" onmouseout="ns_menuhide(this);">E-Shop</a>
</div>

Ссылки находятся внутри <div id=”ns_navigation”> в общем, так сказать, контейнере. А между ссылками находятся div’ы которые будут отображать разделительную картинку. Сами ссылки имеют события onmouseover и onmouseout и это логично. При вызове функции ns_menushow отправляются параметры: this – элемент на который навели курсором мыши, а второй элемент строка содержащая всё названия и url ссылок для выпадающего меню. Очень удобно по определённому символу разделять строку на элементы массива. Я выбрал символ «|» для разделения на пункты меню и знак « = » для разделения заголовка и самой ссылки (ссылки здесь указаны в виде пермалинков).

Чтобы всё красиво выглядело подключаем css-файл в котором пишем:


div#ns_navigation{
margin: 0px;
padding: 0px;
text-align: left;
font: 11px Verdana;
}
div#ns_navigation{
background-color: #000000;
height:19px;
width: 724px; // ширину придётся подстраивать вручную
overflow: hidden; //в IE6 есть баг при котором последний пункт меню дублируется и вставляется под меню, поэтому - скрываем
}
#ns_navigation a{
display: block;
float:left;
text-decoration: none;
color: #FFFFFF;
padding: 3px 14px 2px 14px;
}
#ns_navigation div{ //настраиваем разделительную картинку
margin: 0px;
padding: 0px;
float:left;
width: 1px;
height: 18px;
background: url(ns_dropdown_menu.gif);
}
#ns_navigation a:link, #ns_navigation a:visited{
background-color: #00518c;
}
#ns_navigation a:hover, #ns_navigation a:active{
background-color: #003c63;
}

Внешний вид горизонтального меню готов. Теперь займёмся созданием выпадающего меню.
Подключаем javascript-файл в котором пишем:


var dropmenu = document.createElement("div"); //создаём тэг div куда поместим подменю
var over_head = false; // переменные для определения, держит ли
var over_menu = false; // пользователь мышку на главном или выпавшем меню или нет


// отличная функция, определяющая точные координаты элемента, независимо в каком тэге находится меню. Работает во всех браузерах.
function findPos(obj) {
var curleft = curtop = 0;
if (obj.offsetParent) {
curleft = obj.offsetLeft
curtop = obj.offsetTop
while (obj = obj.offsetParent) {
curleft += obj.offsetLeft
curtop += obj.offsetTop
}
}
// возвращает левую и верхнюю позицию в массиве
return [curleft,curtop];
}


function ns_menushow(menu_head, string_params) { // функция показа меню
var positions = findPos(menu_head); //получаем точную координату элемента
var left = positions[0] - 1; // присваеваем координату переменной left
var top = positions[1] + menu_head.offsetHeight + 1; // присваеваем координату переменной top, но добавляем высоту горизонтального меню.
var params = string_params.split(’|'); // делим строку с параметрами напункты меню
var html = "";
for (i=0; i < params.length; i++){ // в цикле делим пункты меню
title = params[i].split(’='); // на заголовки и адреса и генерируем ссылки
html += "<a href='" + title[1] + "'>" + title[0] + "";
}
document.body.appendChild(dropmenu); // помещаем div на страницу
dropmenu.innerHTML = html; // помещаем в него ссылки
dropmenu.style.left = left + "px"; // задаём левую позицию
dropmenu.style.top = top + "px"; // задаём верхнюю позицию
dropmenu.id = ‘ns_dropmenu’; // называем
over_head = true; // а здесь говорим: курсор находится на заголовке меню
}


dropmenu.onmouseover = function(){ // если наводим курсор на выпавшее меню
over_menu = true;
}


dropmenu.onmouseout = function(){ // если убираем курсор с выпавшего меню
over_menu = false;
var tim = setTimeout("ns_clear()", 1500); // через полторы минуты запускаем функцию удаления выпадающего меню
}


var tim;
function ns_clear(){
var dropmenu = document.getElementById(’ns_dropmenu’);
if(!over_menu && !over_head && dropmenu){
// если курсора нет ни на главном меню ни на выпадающем и вообще существует выпадающее меню, то удаляем его.
document.body.removeChild(dropmenu);
clearTimeout(tim);
}
}


function ns_menuhide(){ // если убираем курсор с главного меню
over_head = false;
var tim = setTimeout("ns_clear()", 1500); // через полторы минуты запускаем функцию удаления выпадающего меню
}

Ну вот. Надеюсь в комментариях понятно объясни что и как.
Осталось настроить внешний вид выпадающего меню.


div#ns_dropmenu{
background-color: #EFEFEF;
position: absolute;
width: 160px;
overflow: hidden;
filter:alpha(opacity=75);
opacity:.75;
}
#ns_dropmenu a{
display: block;
text-decoration: none;
color: #FFFFFF;
padding: 5px 20px;
margin: 0px;
}
#ns_dropmenu a:link, #ns_dropmenu a:visited{
background-color: #7392ad;
}
#ns_dropmenu a:hover, #ns_dropmenu a:active{
background-color: #003c63;
}

И добавляем #ns_dropmenu в самую первую инструкцию для горизонтального меню:


div#ns_navigation, div#ns_dropmenu{
margin: 0px;
padding: 0px;
text-align: left;
font: 11px Verdana;
}

В итоге должно получиться нечто такое.
Скачать исходник

Дата: 06.02.2007
»
Категории: Скриптинг
Google     

]]> pmaster ]]>

Симпатично. Забобрил! =)

»

]]> Danaki ]]>

Акстись! Жабаскрипт а не жаба! Ато я уже напрягся :D

»

]]> Никита Селецкий ]]>

Я ж говорю, это другая история ))

»

]]> Игорь ]]>

А можно сделать всё то же самое, только без задержки, вообще не используя жаваскрипт :)
http://www.maxima.lv/
http://2006.arsenals.lv/

»

]]> Никита Селецкий ]]>

Можно. Как вариант.
Мой скрипт хорошь тем что, куда бы ты меню не поместил, выпадающее меню будет вставать куда надо. А задержка не особо заметная.
можно добавить анимацию выпадания.

А вообще это пример не только для того чтобы создавать выпадающее меню, а чтобы показать как создавать динамические объекты с точным позиционированием.

»

]]> Alexandr ]]>

Подскажите, что сделать чтобы при просмотре страници в интернет броузере с этим выпадающем меню , не выскакивала блокировка отого скрипта? в верхней части броузера! изиза этого не хочет работать само меню! приходится разрешать все действия для коректной работы меню!

»

]]> Никита Селецкий ]]>

Блокируется скрипт только в параноидальном браузере Internet Explorer и только если вы открываете станицу локально, т.е. с вашего компьютера. Если вы закачиваете на сервер и заходите на сайт примерно так: http://www.mysitel.com/index.html, то блокировки не будет

»

]]> Alexandr ]]>

Подскажите пожалуйста! что надо дописать в скрипте! чтобы при наводке на выпадающее меню выпадало еще одно меню (подменю в бок в право!!) ???

»

]]> Никита Селецкий ]]>

Так просто подсказать не смогу. Такой скрипт нужно писать.

»

]]> Polya ]]>

Уважаемый Никита Селецкий!
Ваш вар-т выпадающего меню – лучшее, что есть в инете! :-) )
правда, появился маленький “трабл”: все подменю выравнены по левому краю и на мониторах с разрешением, например, 800х600 последнее подменю вылазит за пределы экрана.
я еще начинающий “джава-скриптёр”, поэтому, как говорится, хЕлп ми! :-) )

»

]]> Никита ]]>

Polya, ценное замечание. Будем работать.

»

]]> Polya ]]>

Никита, пожалуйста, работайте побыстрей! :-)
мысленно с Вами! :-) )

»

]]> Hawk ]]>

Хорошее и красивое выпадающее меню, но есть 1 но. Оно почему-то не работает в phpbb форуме, когда пытаюсь вставить на главную страницу. Другие похожие менюшки работали. Может кто подскажет в чём может быть проблема? На пустой странице работает без проблем.

»

]]> Никита ]]>

Hawk, ошибки какие-то выдаёт? Правильно подключили JS и настроили меню? Вообще способ усторевший. Рекомендую менюшки сделанные в http://cssplay.co.uk работают без js-скрипта, кроссбраузерные и легкоподключаемые.

»

Напишите комментарий