Сейчас я расскажу, как можно сделать фиксированное меню средствами jQuery. Как оказалось, это несложно - код состоит всего из нескольких строчек.
Вариант №1
В первом варианте рассмотрим случай, когда «шапка» сайта имеет небольшую высоту (например, 150px) меню расположено под ней, при прокрутке оно фиксируется вверху страницы. В этом варианте страницы все довольно просто и обычно.
Для начала нужно создать страницу.

При помощи CSS устанавливаем высоту «шапки» и создаем правила для блока с меню.
CSS
Теперь переходим к написанию скрипта на jQuery, который будет фиксировать меню вверху страницы при прокрутке.
JavaScript
В скрипте создаем 2 переменные в которые сохраняем значения высоты шапки и отступа блока с меню сверху. Отступ может отсутствовать (как в данном случае). Затем пишем обработчик на событие onScroll
объекта window
. В нем с помощью метода scrollTop()
вычисляем расстояние от верха страницы до текущей позиции скроллера прокрутки. На основании расчета позиционируем блок с меню.
Вариант №2 (Добавлено 18.02.2015)
Второй вариант фиксированного меню более сложный. В нем «шапка» занимает весь экран, меню находится внизу страницы, при прокрутке содержимого к концу страницы, оно «поднимается», до тех пор, пока не достигнет верха, затем меню фиксируется.
При прокрутке страницы к началу, меню также «движется» вместе с содержимым, а когда достигает низа, оно фиксируется.

Нам потребуется следующий CSS-код.
CSS
Скрипт нижнего фиксированного меню на jQuery будет выглядеть немного иначе.
JavaScript
В начале создаем 3 переменных. В h_hght
сохраняем значение высоты «шапки», которая занимает весь экран по высоте, в переменную h_nav
помещаем значение высоты блока с навигацией. В переменной top
будет хранится значение отступа прокрутки сверху, которое будет вычисляться при каждом скролле.
Далее в скрипте в зависимости от значения переменной top
, блоку с навигацией устанавливается значение CSS-правил top
или bottom
.
Таким образом достигается поведение блока с меню, описанное выше.
Ну вот, собственно, и всё.
Я создал 2 простые странички для демонстрации работы обоих вариантов фиксированного меню. При желании вы сможете ознакомиться с ними:
Комментарии
Но есть один нюанс, важный для меня. К сожалению сам пока не смог сделать.
Как сделать так чтобы позиционирование фиксированного блока было относительно родительского блока в котором он находится (родит. блок находится в центре страницы и может смещаться, если перед ним добавить новый модуль), а не как сейчас - относительно края экрана (всей страницы) !??
спасибо
Дело в том, что внизу сайта есть форма обратной связи и, если меню наезжает на нее, выглядит плохо.
Заранее спасибо за код!
Матвей, да я ознакомился со всеми комментариями. Дело в том, что в Вашем совете Вы рекомендуете указать четкое значение, которое мы знаем заранее. Но контент ведь у меня разный. Мне удобно будет или прекращать скролл, как только дойду до нужного блок или отслеживать высоту от нижнего края документа (тк высоту футера с формой обратной связи я знаю).
Сможете еще раз мне помочь?
var block_pos = $('.ваш_блок').offset();
var hide_pos = block_pos.top;
А далее как в моем комментарии
Да, все заработало! Огромное спасибо! Единственное у данное решения есть баг - если изменить окно браузера, то перестает работать скрипт (элемент top не становится static). А вот если перезагрузить страницу, то с новым окном браузера скрипт отрабатывает как надо.
elem.css('top', (h_hght-top)).addClass('my_class');
} else {
elem.css('top', h_mrg).removeClass('my_class');
}
$(document).ready(function(){
setTimeout(function(){
window.scrollTo(0, 0);
}, 1);
});
Ваш вариант дополнил бы так:
if (top+h_mrg < h_hght) {
elem.css('top', (h_hght-top));
} else {
elem.css('top', h_mrg);
}
перед $(window).scroll(function..
Минимализм и простота
А как сделать, чтоб при прокрутке наше меню останавливалось на определенном расстоянии от верха и прокрутка продолжалась уже без него?
var hide_pos = 800; // скролл сверху, где блок должен скрываться
перед проверкой условия в скрипте добавьте еще одну проверку:
if(top > hide_pos){
elem.css('position', 'static');
}
else{
elem.css('position', 'fixed');
}
вместо 800 укажите свое значение
Замечание: для таких не образованных как я, стоит в конце или в начале статьи сделать жирным текстом: не забудьте подключить библиотеки JQuery. Просто для новичка "средствами jquery" было не совсем понятно, что имелось ввиду. Я думал что это какие-то встроенные модули, типа как в html5, не думал, что их нужно подключать отдельно.
Вопрос: я воспользовался первым способом, но моё меню вертикальное и по достижении подвала налазит на него и перекрывает. На разных страницах подвал, естественно, будет не на одном и том же расстоянии от верха. Задача в том, чтобы по достижении подвала меню снова переставало быть фиксированным и прокручивалось вместе с содержимым. Буду весьма признателен, если поможете с решением. Ещё раз спасибо.
Но всё равно можно добавить, в Webbuelder добавьте элемент который прикрепляет файлы, туда добавьте скрипт (если его нет) Затем открываете в Webbuelder редактировать HTML страницы и туда (если не ошибаюсь в тело body добавляете код, так же в head залинкуйте путь скрипту.
Суть в том, что вы вручную добавляете всё что вам нужно, но в отличии редактирования в текстовом файле после компиляции, вы это приписываете в Webbuelder, таким образом не нужно будет каждый раз редактировать файл после компиляции )
Респект тебе и уважение!
Подскажите, пожалуйста, а что делать, если расположение меню до прокрутки bottom: 0px, при этом высота основного фона height: 100%, т.е. высота фона определяется от размера экрана пользователя?
Вы меня очень выручили, а то совсем "нулевая" в JavaScript.
if (top+h_mrg < h_hght) {
elem.css({'top': (h_hght-top), 'background-color' : '#f0f0f0'});
} else {
elem.css({'top': h_mrg, 'background-color' : '#00ff00'});
}
можно менять фон.
Возможно это поможет. Дело в том что в разных случаях (прокрутка и переход по ссылке) координаты блоков рассчитываются по-разному. Поэтому и цвет в меню меняется раньше.
А поподробнее можно? Куда нужно прописать класс narrow в скрипте, чтобы потом его оформить стилями?
if (top+h_mrg < h_hght) {
elem.css('top', (h_hght-top));
elem.addClass('narrow');
} else {
elem.css('top', h_mrg);
elem.removeClass('narrow')
}
понятно даже мне
Только подскажите, как прописать в скрипте высоту в em, а не в пикселях. Сейчас, если вместо 150 поставить, например 8em то ничего не работает.
В первой строке
var h_hght = 8*16; // высота шапки
А что, как-нибудь задать в скрипте, чтобы значения воспринимались в em разве нельзя?
Спасибо!
А как можно его доработать так чтоб доходя до конца страницы фиксированное меню пропадало т.к. в footer верхнее меню дублируется?
и заменить
var h_hght = 150; // высота шапки
на
var h_hght = $('header').height(); // высота шапки
Только в ie работать без этого файла не будет?
RSS лента комментариев этой записи