CoderNotes - заметки программиста

Публикации  »  JavaScript + jQuery
Скидка 65% на Skillbox

Получите скидку 65% на любой курс программирования на популярной образовательной платформе Skillbox!

Подробнее
Бесплатный хостинг + SSL-сертификат

Зарегистрируйте домен и получите 2 месяца бесплатного хостинга и SSL-сертификат на 1 год в подарок

Подробнее

Как зафиксировать меню при прокрутке страницы

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

Зафиксировать меню при прокрутке страницы

Чтобы реализовать фиксацию меню с помощью jQuery, необходимо отслеживать прокрутку страницы и при достижении позиции меню его нужно зафиксировать, а при прокрутке обратно вверх, меню нужно снова вернуть в исходное положение.

Предположим, мы имеем такой html-код:

<style>
.header {
  width: 100%;
  height: 150px;
  background: #90dcff;
}
.menu {
  width: 100%;
  height: 80px;
  background: #b5ff90;
  z-index: 10;
}
</style>
<div class="header">
  <p>Это шапка сайта с логотипом и прочим</p>
</div>
<div class="menu">
  <p>Это меню, которое зафиксируется при прокрутке страницы</p>
</div>
<div class="content">
  <p>Какой-то контент 1</p><p>Какой-то контент 2</p><p>Какой-то контент 3</p><p>Какой-то контент 4</p><p>Какой-то контент 5</p><p>Какой-то контент 6</p><p>Какой-то контент 7</p><p>Какой-то контент 8</p><p>Какой-то контент 9</p><p>Какой-то контент 10</p>
  <p>Какой-то контент 11</p><p>Какой-то контент 12</p><p>Какой-то контент 13</p><p>Какой-то контент 14</p><p>Какой-то контент 15</p><p>Какой-то контент 16</p><p>Какой-то контент 17</p><p>Какой-то контент 18</p><p>Какой-то контент 19</p><p>Какой-то контент 20</p>
  <p>Какой-то контент 21</p><p>Какой-то контент 22</p><p>Какой-то контент 23</p><p>Какой-то контент 24</p><p>Какой-то контент 25</p><p>Какой-то контент 26</p><p>Какой-то контент 27</p><p>Какой-то контент 28</p><p>Какой-то контент 29</p><p>Какой-то контент 30</p>
  <p>Какой-то контент 31</p><p>Какой-то контент 32</p><p>Какой-то контент 33</p><p>Какой-то контент 34</p><p>Какой-то контент 35</p><p>Какой-то контент 36</p><p>Какой-то контент 37</p><p>Какой-то контент 38</p><p>Какой-то контент 39</p><p>Какой-то контент 40</p>
  <p>Какой-то контент 41</p><p>Какой-то контент 42</p><p>Какой-то контент 43</p><p>Какой-то контент 44</p><p>Какой-то контент 45</p><p>Какой-то контент 46</p><p>Какой-то контент 47</p><p>Какой-то контент 48</p><p>Какой-то контент 49</p><p>Какой-то контент 50</p>
</div>

Мой вариант скрипта для фиксации меню при прокрутке страницы с использованием jQuery такой:

$(function() {
  menu_top = $('.menu').offset().top;        // запоминаем положение меню
  $(window).scroll(function () {             // отслеживаем событие прокрутки страницы
    if ($(window).scrollTop() > menu_top) {  // если прокрутка дошла до меню
      if ($('.menu').css('position') != 'fixed') {  // проверяем, если меню еще не зафиксировано
        $('.menu').css('position','fixed');  // задаем блоку меню свойство position = fixed
        $('.menu').css('top','0');           // положение в самом верху
        $('.content').css('margin-top','80px'); // делаем отступ, чтобы контент не "скакал" в момент фиксации меню
      }
    } else {                                 // прокрутка страницы обратно вверх достигла место "перехода" меню
      if ($('.menu').css('position') == 'fixed') {  // если меню зафиксировано
        $('.menu').css('position','');
        $('.menu').css('top','');
        $('.content').css('margin-top','');
      }
    }
  });
});

Посмотреть пример в действии (откроется в новом окне)

Несколько дополнительных пояснений к коду:

  • во 2-й строчке я запоминаю положение меню относительно страницы, т.к. при прокрутке после его фиксации это значение будет меняться, а нам нужно запомнить исходное значение, либо вместо переменной menu_top можно использовать конкретное значение, например, в нашем случае 150 (высота шапки перед меню);
  • в 5-й и 11-й строках прежде чем устанавливать свойства, я сначала проверяю, зафиксировано меню или нет, чтобы css-свойства не устанавливались множество раз, пока страница прокручивается пользователем;
  • вместо установки свойств $('.menu').css можно устанавливать и удалять какой-нибудь класс и соответственно, в строках 5 и 11 проверять наличие этого класса в условиях;
  • в 8-й строке при фиксации меню я делаю так же отступ для блока content добавляя margin-top равный высоте меню, т.к. если этого не сделать, меню, поменяв свое свойство position на fixed, перестанет "занимать место" и контент расположиться сразу под шапкой, т.е. "скакнет" вверх и чтобы это компенсировать, я и делаю у контента отступ вверху.

Если у вас есть предложения/замечания, пожалуйста напишите в комментариях.

Категория: JavaScript + jQuery

Книги по теме:

Посмотреть все книги по программированию

Комментарии к статье:

04.02.20   Гость молодец ! спасибо !!
10.09.20   Гость Спасибо!
15.02.21   Гость Добрый день. Можно ли как то реализовать так, чтобы меню закрепилось, а на определенном месте отлипло. Если брать из примера то прилипло оно например с какой то строки, а когда 8 достигло вернулось обратно. Нужно для просмотра большой таблицы, чтобы при прокрутке вес размер листалось пока таблицу смотришь, а когда дальше скролишь чтоб заголовок на верх вернулся.
28.12.21   алекс красиво не работает
23.06.22   Гость Большое спасибо!!!

Добавить комментарий: