Простое раздвижное меню на javascript

Сегодня мы продолжим рассматривать простейшие решения на javascript. Я уже рассказывал о меню на основе вкладок и об организации прайс-листа. В обоих случаях были использованы максимально простые решения. Никаких популярных библиотек jquery и prototype (не то, чтобы я был категорически против фреймворков, но для решения одной простой задачи незачем цеплять лишние файлы).

В этот раз не получится сделать скрипт НАСТОЛЬКО простым, как это получилось в прошлых статьях. Однако, я cчитаю, что один килобайт скрипта против ста килобайт фреймворка – это вовсе неплохой результат.

Итак. В этот раз решил не рассказывать, как я дошёл до этого скрипта (разве это кому-нибудь интересно? :). Просто опишу его. Наш скриптик будет состоять из трёх функций. Первая для плавного показа скрытого элемента, вторая – для скрытия, и последняя функция будет отвечать за то, какое действие должно отрабатываться в данный момент.

Код Javascript

// Эта функция умеет плавно показать блок.
function show(id, height) { // Объявляем функцию. Заданными параметрами будут айдишник элемента и его высота.
var a = document.getElementById('p'+id); // Определяем переменные. Скрытый элемент.
var b = document.getElementById('m'+id); // Определяем переменные. Ссылка, связанная со скрытым элементом.
document.getElementById('p'+id).style.display=''; // Теперь наш блок не скрыт злобным свойством display:none (тотальное скрытие элемента). Насколько я помню, его пришлось назначать скрытому элементу для «лучших» браузеров.
b.className='sel'; // Присваиваем ссылке класс выделения.
if (a.offsetHeight < height) { // Пока высота меньше заданой вами высоты
a.style.height = (a.offsetHeight + 10) + "px"; // прибавляем по 10 пикселов к текущей высоте.
setTimeout (function(){show(id, height)}, 30); // Запускаем скрипт заново через 30 миллисекунд.
}
else {bl=0;document.getElementById('p'+id).style.overflow='visible'}; // Или ставим маркер bl равный нулю, а элементу присваиваем свойство overflow:visible (то есть, элемент теперь будет отображён полностью, даже если не влазит в свои рамки).
}

// Эта функция умеет плавно спрятать блок с глаз долой. Здесь всё аналогично, только наоборот.
function hide(id) {
var a = document.getElementById('p'+id);
var b = document.getElementById('m'+id);
document.getElementById('p'+id).style.overflow='hidden';
if (a.offsetHeight > 1) {
a.style.height = (a.offsetHeight - 10) + 'px';
setTimeout (function(){hide(id)}, 30);
}
else {bl=0;b.className='';document.getElementById('p'+id).style.display='none';
}
}

var bl=0; // Ставим маркер bl равный нулю по умолчанию.
// А эта функция управляет предыдущими двумя
function showhide(id, height) {
var a = document.getElementById('p'+id);
if(bl==1){return false;} // Если bl равен нулю, значит ничего не делаем.
bl=1; // Иначе присваиваем маркеру bl значение 1, чтобы до конца обработки рабочих функций дёрганье управляющей функции не имело никакого эффекта. Иначе могут вылазить глюки (если быстро кликать).
if(a.offsetHeight < height) // Если высота элемента меньше заданной высоты
{show(id, height)} // значит запускаем функцию показа,
else // иначе
{hide(id)} // запускаем функцию скрытия.
}

Ну, и конечно живой пример менюхи.

Логика проста. При запуске функции мы задаём id элемента и высоту. В зависимости от того, какое значение высоты элемента в данный момент, начинаем показывать или скрывать элемент. Плавность достигается банально за счёт увеличения высоты через определённый промежуток времени. Скорость отображения/скрытия можно регулировать. Вы наверно заметили пляски с бубном вокруг параметра bl – так делать пришлось из-за глюков, появляющихся в случае быстрого кликанья по ссылке. Также для «лучших» браузеров (догадались для каких? :) понадобилось скрывать элементы с помощью display:none.

Конечно скрипт писался для конкретной менюшки, поэтому подразумеваются определённые идентификаторы. Их можно поменять на свои, немного разобравшись в коде скрипта. Удачи.

Вроде всё просто. Надеюсь, что мои комментарии понятны. Если нет – прошу в комменты. Также уверен, что подобный скрипт можно написать и проще и более понятно, однако данное решение мне нравится. Буду рад, если вы пришлёте свои варианты реализации.

Продолжаю обмен постовыми.

Для начинающих веб-мастеров будут полезны бесплатные видеоуроки по div верстке сайта из psd-макета.

А также Cobber обещал отомстить двумя ссылками за постовой. Что ж не побоимся и поставим его :) Дело в том, что он проводит акцию Месть за ссылку. Обещал отомстить троекратно, ежели опубликовать анонс его акции :)

Подпишитесь на обновления блога

Получить в подарок мини-книги и 21-дневный тренинг по личностному росту.

Подписаться на рассылку «Инструменты Интернет для онлайн бизнеса»

Поделиться ссылкой:


Комментарии:

23.01.2010 20:55:58
#1 Игорь

Спасибо за статью =)

03.02.2010 14:48:51
#2 Иван

спасибо. успехов

03.02.2010 15:43:32

Игорь, Иван, пожалуйста. Заходите ещё.

11.02.2010 16:29:24
#4 Артём

Never Lex а как бы мне эту менюшку скачать готовую в архиве? Если не трудно скинь на почту уж очень нужно.

11.02.2010 21:00:13

Артём, можно просто перейти на страничку с примером и сохранить её. И никакие архивы не нужны :)

15.02.2010 07:54:42
#6 Андрей

У меня глюки с менюшкой при работе в лучшем браузере, не понимаю в чем может быть дело.
1.) по умолчанию - текст не скрыт.
2.) после запуска функции скрытия - скрипт перестает работать.

15.02.2010 08:28:09

Андрей, очень странно. Скорее всего у вас проблемы с браузером. Напишите мне в icq или почту.

15.02.2010 08:38:17
#8 Андрей

Ваш пример работает во всех браузер, наверное я что-то неправильно копирую или вставляю. Сейчас скину вам урл сайта на почту.

28.03.2010 16:47:34
#9 Михаил

а вы не подскажете как сделать что бы при переходе по ссылке отдел оставался открытым???

28.03.2010 20:01:43

Михаил, это уже на PHP нужно прописывать.

08.04.2010 14:29:31
#11 trikadin

Хм. Так и не понял «пляски с бубном вокруг параметра bl». Поясните, ладно? Очень нужно, но не понимаю, как работает.

08.04.2010 18:59:21
#12 trikadin

Всё. Догнал. Спасибо)

12.04.2010 07:32:45
#13 Олег

Круто! спасибо за менюшку))

18.04.2010 13:15:36
#14 antoxa-ua

а прикольно сделанно

29.04.2010 15:26:47
#15 K-89

Изменил меню, сделал так, чтоб в открывался под каталог, а потом ещё подподкатало. И сталкнулся с проблемой. Когда открывается ПодПодкаталог он залазит на всё меню которое ниже него. Как исправить не подскажете. заранее спасибо!

29.04.2010 15:28:09

K-89, киньте в почту кодом :)

29.04.2010 15:40:59
#17 K-89

Вот посмотрите: _http://asta-travel.com/hotels-in-russia.html
Меню справо. В IE нормально, но в Mozile всё ужасно. Попробуйте раскрыть всё полностью. И увидите. Спасибо.

29.04.2010 15:42:10
#18 K-89

Описался СЛЕВО меню )

29.04.2010 15:46:37

K-89, мда. Чудеса с CSS :) Подберите нужную высоту, чтобы не ездило по всему экрану :) Зачем, например, Питер и Москва раскрываются аж на 400 пикселей?

29.04.2010 15:47:46
#20 K-89

Щас изменю, результата от этого не будет(

29.04.2010 15:49:58

K-89, сделайте подменю высотой в 200 пикселей, например, а подподменюшки высотой в 40 пикселей. Выезжать и не будет.

29.04.2010 15:52:56
#22 K-89

у меня будет список гостиниц большим, 5звёзд = например надо 100пикселей, 4з.=150пикселей, И надо чтобы при открытии всего меню оно не наезжало например Питерские гостиницы на Московские... Спастбо.

10.05.2010 15:56:23
#23 wacker

спасибо!

17.06.2010 21:19:39
#24 goo

А это меню индексируется? И какие ссылки ставить! Спасибо

17.06.2010 21:43:07

goo, конечно индексируется. А что с ссылками то?

18.06.2010 11:27:37
#26 goo

Спасибо! А ссылками просто затупил!

06.07.2010 12:26:30
#27 Виха

А если помучаться и доработать так, чтобы при открытии следующего пункта меню, предыдущий закрывался? Что то мне подсказывает, что для Вас это работы на несколько минут, а нам, простым смертным, было бы удобно и приятно. Заранее спасибо.

06.07.2010 12:46:12

Виха, а вы просто повесьте 2 события на клик или доработайте функцию. Чтобы клик одновременно закрывал все подменюшки и открывал нужную.

07.07.2010 12:05:46
#29 max.gavrilov

Как на счет кроосбраузерности? У меня в опере не отображает!

09.07.2010 18:59:38
#30 Виха

Never Lex, Спасибо за саму идею менюхи, доработал как мог, в силу своих скудных познаний :-) но реализовать свою идею не смог. Хотя бы намекните как устроить проверку на открытые подменю, чтобы на них запустить функцию hide.
max.gavrilov, А я как раз в ОПЕРЕ и тестирую - все прекрасно работает. Версия ОПЕРЫ - 9.64

09.07.2010 19:08:29
#31 Виха

max.gavrilov, А вот в 7 ИЕ получился глюк - при открытии странички с таким меню, меню получилось полностью развернуто. При попытке нажать на заголовок меню получается бесконечный цикл - закрывается и открывается меню, при этом повторное нажатие на заголовок не приводит ни к какому результату.
Never Lex,
И при повторном прочтении совета по поводу моей просьбы - обратил внимание на небольшое уточнение - сначала закрыть ВСЕ подменю, а затем открыть нужное. Попробую сделать, отпишусь по результатам.

09.07.2010 20:18:13
#32 Виха

Never Lex.
Спасибо, немного пораскинув мозгами :-), пришел к выводу, что в событии onclick в начале просто нужно добавить функцию hide(id), где id - номер закрываемого подменю. Благо у меня пока что только два подменю. Но при увеличении количества подменю, просто добавляются еще функции hide(id) в каждое подменю. Можно помучаться и сделать универсальную функцию, которая будет закрывать все подменю и не надо будет мучаться с добавление в каждое событие onclick, но ночь на улице и глазки слипаются, да и необходимости бешенной нет. Пока мои потребности удовлетворены.
Еще раз спасибо за скрипт.

10.07.2010 07:44:21

Виха, пожалуйста. Всегда приятней самому что-то разработать, а не взять готовый код. Правда? :)

11.07.2010 09:53:34
#34 Виха

Never Lex,
Это с какой стороны посмотреть :-) Если что то соображаешь, то конечно приятно самому разработать или доработать и получить результат, а если просто хочется красивую фишку получить, а знаний никаких? Вот тут на помощь приходят такие специалисты как Вы. У меня просто опыта работы с java+html практически нет. Литературы нормальной найти не могу. Вот и приходится использовать чьи то наработки+метод научного тыка.

12.07.2010 07:03:33

Виха, имхо, намного проще заплатить денежку программисту, чтобы он всё настроил. Если нет желания в этом разбираться конечно. А если хочется понять что и как работает, то нужно практиковаться :)

01.08.2010 17:51:01
#36 Жека

Установил этот js в своё меню, у моей ссылке по которой кликаю есть стиль прописанный через класс, когда я на неё нажимаю этот стиль слетает, подскажите что нужно прописать в js что-бы стиль не слетал?

03.08.2010 08:47:56

Жека, по идее стиль слетать не должен. Напишите лучше на почту с указанием кода. Будет проще разобраться.

14.08.2010 16:04:54
#38 demiurge

Наконец-то я нашёл это!!!
Ну просто наигромнейшое спасибо:)

31.08.2010 18:36:45
#39 папазол

Помню давно искал такую классную менюху, но отчаялся и плюнул на это дело. Вот сейчас подумываю о смене меню.Пример сохранил-спасибо вам!

18.09.2010 14:48:52

Хороший скрипт - утянул себе на сайты)

19.09.2010 15:53:50
#41 Шухрат Ерматов

Спасибо большое, как же я сам не догадался до этого простого способа!? А я думал надо подключать effects.js... В общем хочу внедрить ваш скрипт в ajax

16.12.2010 11:59:48

Интересный вариант.
Но я бы сделал иначе - подключил бы jquery, потом бы сделал 5 ссылок и 5 скрытых блоков. При нажатии на ссылку блок с соответствующим id переходит из скрытого в видимый через slideToggle. Кода вышло бы еще меньше, причем заметно _)
А если подключать тот же кверик с сервера разработчика, то он однажды закешируется и потом никаких «стокилобайтовых» файлов загружать не надо. Да и ужатый он весит всего 25кб.
Хотя, опять же, если больше jq нигде не юзается, то, и правда, нефиг его цеплять.

22.02.2011 09:24:10
#43 Андрей

Здравствуйте я ничё не понял поэтому можно пожалуйста отправить мне на почту готовый скрипт (Andree14@rambler.ru) или я могу дать адрес сайта

21.03.2011 08:43:26
#44 Дима

Почему не работает нормально в IE 8?

21.03.2011 08:49:55

Дима, не знаю, не тестировал. Когда делал это меню, восьмёрки ещё не было. Но по логике должно работать. Чёрт их знает, что опять напридумывали.

21.03.2011 09:05:40
#46 Дима

Тут уже вопрос подымался, по поводу этого, в IE 8 работает, только выводит в развернутом виде, удалось ли узнать в чем дело?

21.03.2011 09:12:43

Дима, только что посмотрел демку в IE8, всё окей. Скорее всего в вашем конкретном примере ошибка. Используйте FireBug для отладки.

21.03.2011 11:35:17
#48 Дима

Оно то все работало! единственное, выводило в начале при загрузке страниы уже в развернутом, виде. Я тут код просто правлю, сайт старый аж с 2003 года. Но разобрался может, кому будет интересно.
Страница у меня просто начиналась с тега html а надо DOCTYPE HTML PUBLIC и т.д., т.е. надо описать документ, чтобы браузер знал с чем он имеет дело - это для IE/

21.03.2011 12:15:02

Дима, ясно тогда почему у меня проблема не возникло. Доктайп нужно всегда указывать. Это одно из обязательных правил.

21.03.2011 16:22:26

спасибо за подробное описание. пригодится

28.03.2011 10:06:24
#51 volody

Действительно, просто и эффективно, можно вставить в любой шаблон и конструктор

06.04.2011 18:17:11
#52 Виха

Пример:
Есть несколько групп, например, телефоны, навигаторы и т.д.
По клику раскрываем группу телефоны. Там подгруппы, например, мобильные, стационарные, радио и т.п. Кликаем по любой подгруппе, например, мобильные. Все хорошо, отлично. Только вот при перезагрузке страницы меню сворачивается. Как сделать, чтобы автоматом разворачивалась нужная группа? Как поставить оператор IF знаю. Не знаю как именно вызвать процедуру разворачивания. Ситуация такова, что при клике на подгруппу перегружается вся страница и изменить это нельзя.

06.04.2011 18:59:00

Виха, конечно перегружается. Это же не AJAX. Нужно средствами PHP регулировать или прямо в HTML странице.

06.04.2011 19:36:36
#54 Виха

PHP недоступен. Только HTML-код можно использовать. Так вот уточню вопрос - как из чистого HTML вызвать функцию show без указания события onclick? Т.е. Чтобы при загрузке страницы сразу выполнялась функция(условия прикуручу сам).

06.04.2011 19:50:28

Виха, навскидку. На нужной странице присвоить диву id="p1" класс class="open", а в CSS прописать правило #p1.open {height: 120px;}

06.04.2011 20:07:41
#56 Виха

Как сложно. Неужели из чистого HTML невозможно просто вызвать функцию, описанную в java-скрипте? Просто вызвать на исполнение, без каких либо условий и ограничений?

06.04.2011 20:43:41

Виха, можно, но тогда после загрузки страницы див будет разъезжаться.

Пропишите в жаваскриптах: window.onload = function () { showhide(2,90); }

06.04.2011 21:28:44
#58 Виха

Спасибо! То что надо! Добавить немного условий и меню будет работать на ура!

23.04.2011 08:23:32
#59 Сергей

Огромное вам спасибо!
Долго искал подобную функцию.

Успехов вам и процветания!!!

11.05.2011 22:50:24
#60 Ушастик

Здесь много вложенных кнопочек - пишете Вы. Я попыталась сделать эти много кнопочек, но в подменю выезжает только одна, остальных не видно. Может, поможете? Ваше меню мне как-то уж очень приглянулось...
Спасибо.

12.05.2011 06:52:42

Ушастик, напишите в почту, пришлите код. Разберёмся :)

23.06.2011 12:22:17
#62 виталий

Люди добрые, помогите кто чем может... сил уже никаких нету... я в html полный валет... помоги разобраться с менюхой.. в IE не работает...... пишите на почту yurchenkovit@mail.ru или в асю, с пометкой дядя вася идет на помощь :) спасибо

23.10.2011 08:46:31
#63 автор

мне тоже что-то тяжко дается

10.11.2011 11:38:38
#64 Светлана

о, ну тоже нормальная вещица, только посложнее той, что в соседней теме...

23.12.2011 07:35:20
#65 Сережа

Вот где вы раньше были я как раз искал такое меню для своего сайта. Спасибо большое надо попробовать обязательно ..

15.06.2012 07:29:32

Never Lex, спасибо за пояснение! Провел опрос и оказалось, что пользователем моего сайта больше нравится обычное меню, так что оставил простое меню)

28.06.2012 14:16:28
#67 Влад

Спасибо большое! Очень помог :)

13.12.2012 15:27:14
#68 Буба Касторский

Добрый день, уважаемые!
Так понравился пример, что решил интегрировать его в сайт.
И даже получилось, но не до конца.
Уже больше суток бьюсь, не могу понять, почему не работает корректно.
Вписал скрипт для страницы на сайте и js работает корректно во всех браузерах, кроме IE. Причем, сама ссылка с примером что тут работает нормально и в IE, а на моей странице - нет.
Ребята, помогите разобраться. Кому будет не сложно, дайте знать на почту - mr.selcet@gmail.com

31.03.2013 12:34:29
#69 Сергей

Здравствуйте, я новичок в javascript-программинге, но появилась срочная задача повесить на сайт кнопку по нажатию которой разворачивался б <div>. Немного покурил Ваш скрипт и получилось, но вот разворачивающийся вертикально не совсем уместен по дизайну, а как развернуть его решение не нашел...
Если будет возможность подсказать как справаразмещеная кнопка могла б развернуть его горизонтально, наведите на светлую мысль!
Заранее благодарю!
(или ссылку на пример, только без CSS3)

01.12.2014 14:46:34

Ссылка на демо меню - не работает

Оставьте комментарий [форматирование]

Пожалуйста, воздержитесь от спама и идиотских высказываний. Жёсткая модерация. Ссылки закрыты атрибутом nofollow, а значит не несут пользы для продвижения!
Ссылки на всё кроме личных блогов и тематических блогов, сходных по тематике с данным, вырезаются.



Мой Telegram канал
Мой RSS фид