Простое раздвижное меню на 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 обещал отомстить двумя ссылками за постовой. Что ж не побоимся и поставим его :) Дело в том, что он проводит акцию Месть за ссылку. Обещал отомстить троекратно, ежели опубликовать анонс его акции :)
Поделиться ссылкой:
Комментарии:
Never Lex а как бы мне эту менюшку скачать готовую в архиве? Если не трудно скинь на почту уж очень нужно.
У меня глюки с менюшкой при работе в лучшем браузере, не понимаю в чем может быть дело.
1.) по умолчанию - текст не скрыт.
2.) после запуска функции скрытия - скрипт перестает работать.
Ваш пример работает во всех браузер, наверное я что-то неправильно копирую или вставляю. Сейчас скину вам урл сайта на почту.
а вы не подскажете как сделать что бы при переходе по ссылке отдел оставался открытым???
Хм. Так и не понял «пляски с бубном вокруг параметра bl». Поясните, ладно? Очень нужно, но не понимаю, как работает.
Изменил меню, сделал так, чтоб в открывался под каталог, а потом ещё подподкатало. И сталкнулся с проблемой. Когда открывается ПодПодкаталог он залазит на всё меню которое ниже него. Как исправить не подскажете. заранее спасибо!
Вот посмотрите: _http://asta-travel.com/hotels-in-russia.html
Меню справо. В IE нормально, но в Mozile всё ужасно. Попробуйте раскрыть всё полностью. И увидите. Спасибо.
у меня будет список гостиниц большим, 5звёзд = например надо 100пикселей, 4з.=150пикселей, И надо чтобы при открытии всего меню оно не наезжало например Питерские гостиницы на Московские... Спастбо.
А если помучаться и доработать так, чтобы при открытии следующего пункта меню, предыдущий закрывался? Что то мне подсказывает, что для Вас это работы на несколько минут, а нам, простым смертным, было бы удобно и приятно. Заранее спасибо.
Never Lex, Спасибо за саму идею менюхи, доработал как мог, в силу своих скудных познаний :-) но реализовать свою идею не смог. Хотя бы намекните как устроить проверку на открытые подменю, чтобы на них запустить функцию hide.
max.gavrilov, А я как раз в ОПЕРЕ и тестирую - все прекрасно работает. Версия ОПЕРЫ - 9.64
max.gavrilov, А вот в 7 ИЕ получился глюк - при открытии странички с таким меню, меню получилось полностью развернуто. При попытке нажать на заголовок меню получается бесконечный цикл - закрывается и открывается меню, при этом повторное нажатие на заголовок не приводит ни к какому результату.
Never Lex,
И при повторном прочтении совета по поводу моей просьбы - обратил внимание на небольшое уточнение - сначала закрыть ВСЕ подменю, а затем открыть нужное. Попробую сделать, отпишусь по результатам.
Never Lex.
Спасибо, немного пораскинув мозгами :-), пришел к выводу, что в событии onclick в начале просто нужно добавить функцию hide(id), где id - номер закрываемого подменю. Благо у меня пока что только два подменю. Но при увеличении количества подменю, просто добавляются еще функции hide(id) в каждое подменю. Можно помучаться и сделать универсальную функцию, которая будет закрывать все подменю и не надо будет мучаться с добавление в каждое событие onclick, но ночь на улице и глазки слипаются, да и необходимости бешенной нет. Пока мои потребности удовлетворены.
Еще раз спасибо за скрипт.
Never Lex,
Это с какой стороны посмотреть :-) Если что то соображаешь, то конечно приятно самому разработать или доработать и получить результат, а если просто хочется красивую фишку получить, а знаний никаких? Вот тут на помощь приходят такие специалисты как Вы. У меня просто опыта работы с java+html практически нет. Литературы нормальной найти не могу. Вот и приходится использовать чьи то наработки+метод научного тыка.
Установил этот js в своё меню, у моей ссылке по которой кликаю есть стиль прописанный через класс, когда я на неё нажимаю этот стиль слетает, подскажите что нужно прописать в js что-бы стиль не слетал?
Помню давно искал такую классную менюху, но отчаялся и плюнул на это дело. Вот сейчас подумываю о смене меню.Пример сохранил-спасибо вам!
Спасибо большое, как же я сам не догадался до этого простого способа!? А я думал надо подключать effects.js... В общем хочу внедрить ваш скрипт в ajax
Интересный вариант.
Но я бы сделал иначе - подключил бы jquery, потом бы сделал 5 ссылок и 5 скрытых блоков. При нажатии на ссылку блок с соответствующим id переходит из скрытого в видимый через slideToggle. Кода вышло бы еще меньше, причем заметно _)
А если подключать тот же кверик с сервера разработчика, то он однажды закешируется и потом никаких «стокилобайтовых» файлов загружать не надо. Да и ужатый он весит всего 25кб.
Хотя, опять же, если больше jq нигде не юзается, то, и правда, нефиг его цеплять.
Здравствуйте я ничё не понял поэтому можно пожалуйста отправить мне на почту готовый скрипт (Andree14@rambler.ru) или я могу дать адрес сайта
Тут уже вопрос подымался, по поводу этого, в IE 8 работает, только выводит в развернутом виде, удалось ли узнать в чем дело?
Оно то все работало! единственное, выводило в начале при загрузке страниы уже в развернутом, виде. Я тут код просто правлю, сайт старый аж с 2003 года. Но разобрался может, кому будет интересно.
Страница у меня просто начиналась с тега html а надо DOCTYPE HTML PUBLIC и т.д., т.е. надо описать документ, чтобы браузер знал с чем он имеет дело - это для IE/
Действительно, просто и эффективно, можно вставить в любой шаблон и конструктор
Пример:
Есть несколько групп, например, телефоны, навигаторы и т.д.
По клику раскрываем группу телефоны. Там подгруппы, например, мобильные, стационарные, радио и т.п. Кликаем по любой подгруппе, например, мобильные. Все хорошо, отлично. Только вот при перезагрузке страницы меню сворачивается. Как сделать, чтобы автоматом разворачивалась нужная группа? Как поставить оператор IF знаю. Не знаю как именно вызвать процедуру разворачивания. Ситуация такова, что при клике на подгруппу перегружается вся страница и изменить это нельзя.
PHP недоступен. Только HTML-код можно использовать. Так вот уточню вопрос - как из чистого HTML вызвать функцию show без указания события onclick? Т.е. Чтобы при загрузке страницы сразу выполнялась функция(условия прикуручу сам).
Как сложно. Неужели из чистого HTML невозможно просто вызвать функцию, описанную в java-скрипте? Просто вызвать на исполнение, без каких либо условий и ограничений?
Спасибо! То что надо! Добавить немного условий и меню будет работать на ура!
Здесь много вложенных кнопочек - пишете Вы. Я попыталась сделать эти много кнопочек, но в подменю выезжает только одна, остальных не видно. Может, поможете? Ваше меню мне как-то уж очень приглянулось...
Спасибо.
Люди добрые, помогите кто чем может... сил уже никаких нету... я в html полный валет... помоги разобраться с менюхой.. в IE не работает...... пишите на почту yurchenkovit@mail.ru или в асю, с пометкой дядя вася идет на помощь :) спасибо
о, ну тоже нормальная вещица, только посложнее той, что в соседней теме...
Вот где вы раньше были я как раз искал такое меню для своего сайта. Спасибо большое надо попробовать обязательно ..
Never Lex, спасибо за пояснение! Провел опрос и оказалось, что пользователем моего сайта больше нравится обычное меню, так что оставил простое меню)
Добрый день, уважаемые!
Так понравился пример, что решил интегрировать его в сайт.
И даже получилось, но не до конца.
Уже больше суток бьюсь, не могу понять, почему не работает корректно.
Вписал скрипт для страницы на сайте и js работает корректно во всех браузерах, кроме IE. Причем, сама ссылка с примером что тут работает нормально и в IE, а на моей странице - нет.
Ребята, помогите разобраться. Кому будет не сложно, дайте знать на почту - mr.selcet@gmail.com
Здравствуйте, я новичок в javascript-программинге, но появилась срочная задача повесить на сайт кнопку по нажатию которой разворачивался б <div>. Немного покурил Ваш скрипт и получилось, но вот разворачивающийся вертикально не совсем уместен по дизайну, а как развернуть его решение не нашел...
Если будет возможность подсказать как справаразмещеная кнопка могла б развернуть его горизонтально, наведите на светлую мысль!
Заранее благодарю!
(или ссылку на пример, только без CSS3)
Спасибо за статью =)