Блог о SEO оптимизация и поисковое продвижение
12 Дек
ТЗ. На сайте требуется сделать плавающее вертикальное меню (чтобы при скроллинге страницы меню всегда было навиду). Задача усложняется тем, что вертикальное меню идёт не от самого верха — разбиение на колонки начинается после шапки и горизонтального меню. Следовательно, вертикальное меню должно плавать только тогда, когда его верхняя граница скрывается за верхним краем области просмотра браузера.
Для реализации плавания меню я буду использовать JavaScript и его высшее воплощение — jQuery. Исторически так сложилось, что для данного сайта я использую jQuery версии 1.2.6, потому можно использовать мой пример на фреймворке моей версии и выше. Подключаем jQuery:
<html> <head> ... <script src="js/jquery-1.2.6.js" type="text/javascript"></script> </head>
Примерно так выглядит HTML-код самого меню (за исключением технических моментов, не касающихся данной темы):
<div id="lmenu"> <ul> <li><a href="page-1.html''>Страница 1</a> <li><a href="page-1.html''>Страница 2</a> <li><a href="page-1.html''>Страница 3</a> ... </ul> </div>
Ключевым моментом здесь является присвоение слою меню идентификатора «lmenu» — можно поименовать любым другим уникальным именем и далее обращаться к элементу по этому имени. Немного о стилях. Чтобы иметь возможность изменять положение по вертикали слою меню, ему надо задать абсолютное позиционирование. При этом надо учеть, что абсолютно позиционированные элементы не участвуют в разметке страницы (элементы могут накладываться друг на друга, если не задать дополнительные отступы). Вот мои стили для меню и контентной части (которая располагается справа от меню):
#lmenu { position:absolute; top: 357px; width: 250px; } DIV.content { margin: 10px 10px 0 0; float: right; width: 675px; }
Значение «top: 357px;» было определено заранее. При помощи JavaScript. Для этого в страницу был вставлен следующий JS-код:
<script type = "text/javascript"> $(document).ready(function () { alert ($('#lmenu').css('top')); } </script>
Этот скрипт отобразил в модальном окне свойство «top» моего меню — то значение, которое было принято при разметке страницы браузером изначально, без явного указания. Это число нам ещё пригодится. Теперь всё готово к тому, чтобы написать основной код, обеспечивающий эффект плавания меню.
<script type = "text/javascript"> // какая часть окна проскроллена - начальное значение var scroll_top = 0; // этот код будет выполнен сразу после загрузки документа: $(document).ready(function(){ // отступ меню от верхнего края страницы var lmenu_top = parseInt ($('#lmenu').css('top')); // смещение меню по вертикали - начальное значение var offset_lmenu = 0; // этот код будет выполнен при скроллинге страницы: $(window).scroll(function () { // какая часть окна проскроллена (в пикселях) scroll_top = $(document).scrollTop(); // меняем положение меню, если это нужно if (scroll_top > lmenu_top || offset_lmenu > 0) { // новое значение смещения меню offset_lmenu = scroll_top - lmenu_top; // перетаскиваем меню $('#lmenu').animate({top:lmenu_top+offset_lmenu},{duration:300,queue:false}); } }); }); </script>
Ключевую роль здесь играет функция $('#lmenu').animate () — она анимировано изменяет свойство «top» нашего меню. {duration:300,queue:false} — это время выполнения эффекта в миллисекундах. Задержку можно указать просто числом, но тогда меню при скроллинге дёргается.
Далее решено было добавить к меню кнопку «вверх» — так, чтобы эта кнопка появлялась тогда, когда меню начинает плыть вниз, и пропадала, когда меню доплывает до верхней части границы. К меню добавляем ещё один пункт:
<li id="scroll_on_top"><input type="button" value="Вверх" onClick="scrollit()">
При помощи стилей делаем этот пункт изначально невидимым:
#scroll_on_top { display: none; }
Описываем функцию, которая будет выполняться при нажатии кнопки «Вверх»:
<script type = "text/javascript"> function scrollit () { for (i=scroll_top; i>200; i=i-200) { self.scroll(1,i) } self.scroll(1,0) } </script>
Здесь используется ещё не упомянутая переменная «scroll_top» — её значение будем получать во время скроллинга по странице:
<script type = "text/javascript"> $(window).scroll(function () { scroll_top = $(document).scrollTop(); } </script>
При нажатии на кнопку «Вверх» запускается цикл, в котором значение проскролленности страницы уменьшается от текущего значения до нуля при помощи функции self.scroll (1,i). Для того, чтобы показать и скрыть кнопку «Вверх» в нужный момент используются следующие инструкции соответственно:
$('#scroll_on_top').css('display','list-item'); $('#scroll_on_top').css('display','none'); </pre> Собираем всё вышеописанное в кучу. Теперь без комментариев, чтобы не загружать код: <pre lang="javascript" line="1" escaped="true"><script type = "text/javascript"> var scroll_top = 0; $(document).ready(function(){ var lmenu_top = parseInt ($('#lmenu').css('top')); var offset_lmenu = 0; $(window).scroll(function () { scroll_top = $(document).scrollTop(); if (scroll_top > lmenu_top || offset_lmenu > 0) { if (offset_lmenu == 0) { $('#scroll_on_top').css('display','list-item'); } offset_lmenu = scroll_top - lmenu_top; if (offset_lmenu < 0) { offset_lmenu = 0; $('#scroll_on_top').css('display','none'); } $('#lmenu').animate({top:lmenu_top+offset_lmenu},{duration:300,queue:false}); } }); }); function scrollit () { for (i=scroll_top; i>200; i=i-200) { self.scroll(1,i) } self.scroll(1,0) } </script>
Сайт, для которого всё это делалось, сгорел в атмосфере, потому рабочий пример сейчас я вам даже не покажу. 🙂
Запись опубликована 12 декабря 2009 года. Пост окончен, но в рубрике «Web-кодинг» есть не менее интересные посты:
RSS подписка (как это?) поможет вам не пропустить ничего интересного на этом блоге.
На «Плавающее боковое меню — заплыв с jQuery» получено 16 отзывов
Просто чудеса программирования! Это очень удобно для пользователя — когда меню всегда перед глазами и есть возможность оказаться в начале страницы, нажав кнопку «вверх»! Молодец, круто зажёг)))
Спасибо, афтар, как всегда, жжот 🙂
интересно и познавательно, конечно... только физика движения в опере, например, не очень как-то... дергается и не успевает за прокруткой
Конкретный пример, на который есть ссылка в посте, проверял на Опере 10.00 alpha — меню плавает плавно. Пишите, пожалуйста, в каком браузере, в какой конкретно версии есть проблемы отображения. И ссылку на ваш пример, если есть
Столкнулся с проблемой,что происходит наложение слоей. меню накладывается на контент. присвоил в ксс шапке сайта блоку header значение relative. Далее у меня постоянно держался отступ от окна браузера.
Вот пару строк,которые спасли ситуацию.может пригодится кому =)
$(document).ready (function () {
var menuBoundary = document.getElementById ('menu').offsetTop;
$(window).scroll (function () {
var floatTop = Math.max ($(document).scrollTop () — menuBoundary, 0);
$('#menu').animate ({top:floatTop}, {duration:300, queue:false});
});
});
Спасибо, Дима
Ах да,совсем забыл описать принцип работы его. Данный скрипт работает след образом: если шапка сайта (в моем случае блок хеадер) находится в видимой зоне окна браузера,то верхней границей меню служит расстояние,заданное в пикселях от верхней границы окна (а если точно от самой верхушки сайта. учитывается и расстояние до логотипа если есть таковой). как только блок хеадер пропадает из видимой области, меню прижимается к верхней границе окна браузера.) надеюсь понятно описал.
Ключом здесь является функция Math.max,
которая выбирает максимум из верхней границы области прокрутки и исходным положением меню, тем самым не позволяя меню оказаться выше, чем оно находилось изначально.
П.С. ОБъедените если не трудно,забылся просто)
Вроде и так понятно 🙂
Ну если потом под пивко надумаю внести какие-либо коррективы...
В любом случае, спасибо
Спасибо, интересное решение,
а главное простое!
Наздоровье, Antonio. Вижу, у вас так же реализовано плаванье рекламы от Гугла
Почему когда изменяеш разрешение монитора меню «уезжает» в другое место
Как это можно исправить?
Пожалуйста, пример, и подробности: с какого разрешения на какое меняешь, в какой момент уезжает меню, куда уезжает, в каком браузере
Я наверно немного неправильно выразился
На Опере 10 61 при прокручивании меню плывет вниз, но обратно возвращается не на то место с которого «стартовало», а нежу
На ИЕ8 положение меню выше чем должно быть
Сайтик:
kvatra.org/?page=teach&menu=sites
Аха, вижу. Скорее всего причина в том, что для #lmenu в стилях указано: top:18% — значение в процентах. Попробуйте задать значение в пикселях или других абсолютных величинах
Помогло, спачибо
Ваше SEO-мнение
Я прошу высказать своё мнение, а не оставить ссылку на раскручиваемый сайт. В любом случае, ссылки в комментариях у меня закрыты от индексации, если интересует качественный обмен ссылками -обращайтесь