Простое раздвижное меню на 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 что-бы стиль не слетал?






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