Sheensay → Вебразработка → Фиксированные меню, блоки при прокрутке страницы

Фиксированные меню, блоки при прокрутке страницы

08.11.2021

Как сделать эффект залипания при прокручивании страницы на блоках навигации, меню и любых других без дёрганий и анимации. Используем обычный CSS без JS, а также рассмотрим вариант на jQuery и нативный ванильный JavaScript

  • Используем CSS — position:sticky
  • Как сделать залипающую шапку
  • Как сделать залипающий подвал
  • Используем Sticky JS
  • Как сделать фиксированное меню в шапке
  • HTML
  • JavaScript
  • CSS
  • Фиксированный виджет в сайдбаре
  • Q2W3 Fixed Widget — плагин WordPress для фиксации виджета сбоку
  • Как пользоваться
  • Как сделать залипающий виджет, который не налезает на низ сайта
  • HTML
  • JavaScript
  • Делаем залипание в сайдбаре вручную, вариант №2
  • Предварительная подготовка
  • Код HTML
  • Код Javascript
  • В заключение

Используем CSS — position:sticky

Использование CSS-свойства position:sticky с целью достичь эффекта залипания блока внутри родительского контейнера — самый эффективный, простой и нативный способ, который работает во всех браузерах (кроме Internet Explorer, которым уже почти никто не пользуется).

Как сделать залипающую шапку

<style>
.header{position:-webkit-sticky; position:sticky; top:0;}
</style>
<main class="main">
  <header class="header">HEADER</header>
  <article class="content">MAIN CONTENT</article>
  <footer class="footer">FOOTER</footer>
</main>

Посмотреть, как залипает header, и даже покрутить код можно на Codepen

Как сделать залипающий подвал

<style>
.footer{position:-webkit-sticky; position:sticky; bottom:0;}
</style>
<main class="main">
  <header class="header">HEADER</header>
  <article class="content">MAIN CONTENT</article>
  <footer class="footer">FOOTER</footer>
</main>

Посмотреть, как работает залипающий footer — Codepen

Используем Sticky JS

Библиотека на нативном javascript Sticky JS

  1. Качаете файл https://raw.githubusercontent.com/rgalus/sticky-js/master/dist/sticky.min.js
  2. Сохраняете его на хостинге, где расположен сайт, и подключаете его в шаблоне:
    <script src="/путь_до_файла/sticky.min.js"></script>
    
  3. Инициализируете скрипт:
    <script>
       var sticky = new Sticky('.selector');
    </script>
    

    Здесь .selector — это jQuery селектор блока, который должен залипать при прокрутке.

  4. Если нужно, чтобы залипающий блок останавливался, когда заканчивается родительский контейнер, укажите в родительском контейнере атрибут data-sticky-container

Пример HTML:

<div class="row" data-sticky-container>
  <div class="col-2 columns">
    <img src="http://placehold.it/250x250" class="sticky" data-margin-top="20" data-sticky-for="1023" data-sticky-class="is-sticky">
  </div>
  <div class="col-8 columns">
    <h1>Sticky-js</h1>
    <p>Lorem ipsum.....</p>
  </div>
  <div class="col-2 columns">
    <img src="http://placehold.it/250x250" class="sticky" data-margin-top="20" data-sticky-for="1023" data-sticky-class="is-sticky">
  </div>
</div>

<script src="sticky.min.js"></script>
<script>
  var sticky = new Sticky('.sticky');
</script>

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

Как сделать фиксированное меню в шапке

Всё очень просто. Всё будет основываться на том, где находится скролл на текущий момент относительно нашего меню

  • Если скролл ниже, чем верхушка блока нашего меню, включаем залипание
  • Иначе отключаем залипание

Вот и вся логика.
Можете проверить, как работает

HTML

HTML будет представлять собой что-то навроде

<div id="nav">...Тут содержание навигации...</div>

JavaScript

В Javascript будем определять нашу логику

jQuery(document).ready(function($) {
  var

    $window = $(window), // Основное окно

    $target = $("#nav"), // Блок, который нужно фиксировать при прокрутке

    $h = $target.offset().top; // Определяем координаты верха нужного блока (например, с навигацией или виджетом, который надо фиксировать)

  $window.on('scroll', function() {

    // Как далеко вниз прокрутили страницу
    var scrollTop = window.pageYOffset || document.documentElement.scrollTop;

    // Если прокрутили скролл ниже макушки нужного блока, включаем ему фиксацию
    if (scrollTop > $h) {

      $target.addClass("sheensay_fixed");

    // Иначе возвращаем всё назад
    } else {     

      $target.removeClass("sheensay_fixed");
    }
  });

});

Если не хотите включать залипание для мобильных браузеров, вам пригодится такой код:

 // Определяем мобильный браузер
 function MobileDetect() {
   var UA = navigator.userAgent.toLowerCase();
   return (/android|webos|iris|bolt|mobile|iphone|ipad|ipod|iemobile|blackberry|windows phone|opera mobi|opera mini/i.test(UA)) ? true : false;
 }
 jQuery(document).ready(function($) {
   // Если браузер не мобильный, работаем
   if (!MobileDetect()) {
     var

       $window = $(window), // Основное окно

       $target = $("#nav"), // Блок, который нужно фиксировать при прокрутке

       $h = $target.offset().top; // Определяем координаты верха нужного блока (например, с навигацией или виджетом, который надо фиксировать)

     $window.on('scroll', function() {

       // Как далеко вниз прокрутили страницу
       var scrollTop = window.pageYOffset || document.documentElement.scrollTop;

       // Если прокрутили скролл ниже макушки нужного блока, включаем ему фиксацию
       if (scrollTop > $h) {

         $target.addClass("sheensay_fixed");

         // Иначе возвращаем всё назад
       } else {

         $target.removeClass("sheensay_fixed");
       }
     });
   }
 });

CSS

В CSS определяется класс, которым фиксируем меню

.sheensay_fixed {
   position: fixed !important;
   top: 0 !important;
   margin-left: -100%;
   padding-left: 100%;
   background: rgba(255, 0, 0, 0.1);
}

Строки 4, 5, 6 не обязательны, по могут помочь при горизонтальном выравнивании и создании эффекта полосы на всю ширину экрана.
Прозрачность регулируется в background: rgba(255, 0, 0, 0.1);, а именно в последнем параметре 0.1, варируется от 0 (прозрачный) до 1 (непрозрачный), это аналог css свойства opacity

Фиксированный виджет в сайдбаре

Для больших статей дубль содержания статьи в сайдбаре в роли виджета очень удобен, видно всё содержание в категоризованном формате. Также, там можно размещать рекламу или другие виджеты с похожими статьями или чем-то подобным.
Ниже будет приведено несколько вариантов, как сделать залипающий виджет в сайдбаре сбоку от основной статьи.

Q2W3 Fixed Widget — плагин WordPress для фиксации виджета сбоку

Q2W3 Fixed Widget — это Вордпресс-плагин, который позволяет при прокрутке страницы залипать виджетам, расположенным сбоку в сайдбаре.
Q2W3 Fixed Widget

Скачать Q2W3 Fixed Widget из официального репозитория WordPress

Как пользоваться

Вы просто устанавливаете плагин и активируете его. Теперь любой виджет в сайдбаре будет иметь такую галочку

У каждого виджета появляется возможность залипания

У каждого виджета появляется возможность залипания

Как сделать залипающий виджет, который не налезает на низ сайта

Ниже показан вариант, который в основе содержит принцип фиксированной навигации из 1 пункта.
Задача — для определённого виджета сделать залипание, но так, чтобы он не налезал на подвал сайта.
Принцип прост: мы высчитываем несколько переменных, а именно:

  1. Координату Y верха виджета
  2. Высоту виджета
  3. Координату Y подвала сайта

Далее, на событии window.scroll мы считаем текущие координаты верха браузера.

  • Если координата верха браузера выше координаты верха виджета, ничего не делаем, снимаем все эффекты
  • Если прокрутили ниже верха виджета, включаем залипание
  • Если прокрутили ниже координаты подвала минус высота виджета или, проще говоря, начали налезать на подвал, отключаем залипание, включаем прописку над подвалом

HTML

<body>
  <div class="header">Header</div>
  <div class="body clearfix">
    <div class="main">
... Основное содержимое ...
    </div>
    <div class="sidebar">
... Содержимое сайдбара ...
      <div class=widget>
... Содержимое виджета ...
</div>
    </div>
  </div>
  <div class="footer">Подвал</div>
</body>

JavaScript

Перед скриптом необходимо загрузить jQuery

jQuery( document ).ready(function( $ ) {
	var
			$window = $( window ), // Основное окно

			$target = $( "#fixed_scroll" ), // Блок, который нужно фиксировать при прокрутке

			$bottom = $( '#footer' ), // Нижний блок, за который нельзя заходить

			$top = $target.offset().top, // Определяем координаты верха нужного блока 

			$height = $top + $target.outerHeight(), // Определяем координаты низа $target блока // Блок, который нужно фиксировать при прокрутке

			$bottom = $bottom.offset().top; // Определяем координаты низа нижнего блока // Нижний блок, за который нельзя заходить

	$window.on( 'scroll', function () {

		// Как далеко вниз прокрутили страницу
		var scrollTop = window.pageYOffset || document.documentElement.scrollTop;

		// Если прокрутили скролл ниже макушки нужного блока, но не ниже нижнего блока, включаем ему фиксацию
		if ( scrollTop > $top && scrollTop + $height < $bottom ) {

			$target.css( {
				position : 'fixed',
				top : '0px',
				//width : '1%', // Может пригодиться, если блок не имеет чёткого width
			} );

			// Докрутили до низа
		} else if ( scrollTop > $top && scrollTop + $height > $bottom ) {

			// Координата верха: куда нельзя заходить - минус верх - минус высота блока рекламы
			var top = $bottom - scrollTop - $height;

			$target.css( {
				position : 'fixed',
				top : top,
			} );
		}
		// Иначе возвращаем всё назад
		else {

			$target.attr( 'style', '' );
		}
	} );
});

Если код выше не помогает, проверьте, не использует ли какой-либо из родительских контейнеров css-свойство backface-visibility: hidden;. Если так, то можно заменить код

$target.css( {position : 'fixed',top : 0,} );

на

$target.css( {position : 'absolute',top : $window.scrollTop(),} );

Делаем залипание в сайдбаре вручную, вариант №2

Этот вариант сугубо кастомный, основан на специальном PHP-классе Kama_Contents, реализацию можно увидеть справа в боковой колонке. Выложу код и логику, пригодится.

Предварительная подготовка

Для начала, вам нужно иметь содержание статьи. Также, необходимо подключить jQuery

  • Создаём обёртку под будущую копию содержания статьи
  • Клонируем содержание статьи и добавляем её внутрь обёртки, подчищаем код
  • Отслеживаем координаты верха виджета.
  • Если прокрутили ниже этой верхушки, но не достигли конца статьи, фиксируем меню
  • Если достигли конца статьи, скрываем виджет меню
  • В остальных случаях оставляем как и было изначально

Код HTML

Для примера возьмём содержание этой страницы

<div class="kc__wrap">
<div id="kcmenu" class="kc-title kc_title">Содержание</div>
<ul class="contents">
<li class="top"><a href="#kak-sdelat-fiksirovannoe-menyu-v-shapke">Как сделать фиксированное меню в шапке</a></li>
<li class="sub sub_1"><a href="#html">HTML</a></li>
<li class="sub sub_1"><a href="#javascript">JavaScript</a></li>
<li class="top"><a href="#fiksirovannoe-soderzhanie-stati-v-vidzhete-v-saydbare">Фиксированное содержание статьи в виджете в сайдбаре</a></li>
<li class="sub sub_1"><a href="#predvaritelnaya-podgotovka">Предварительная подготовка</a></li>
<li class="sub sub_1"><a href="#logika">Логика</a></li>
<li class="sub sub_1"><a href="#kod-html">Код HTML</a></li>
<li class="sub sub_1"><a href="#kod-javascript">Код Javascript</a></li>
<li class="top"><a href="#v-zaklyuchenie">В заключение</a></li>
</ul>
</div>

Код Javascript

jQuery(document).ready(function ($) {
    // Определяем мобильный браузер
    function MobileDetect() {
        var UA = navigator.userAgent.toLowerCase();
        return (/android|webos|iris|bolt|mobile|iphone|ipad|ipod|iemobile|blackberry|windows phone|opera mobi|opera mini/i.test(UA)) ? true : false;
    }

// Если не мобильная версия сайта и содержание статьи существует
if (!MobileDetect() && $('.kc__wrap').length) {

    // В сайдбар добавляем обёртку для дубля содержания статьи
    $('.sidebar').append('<section class="widget" id="post-content-list"><div class="widget-wrap" id="widget-wrap-content-list"></div></section>');

    // Клонируем содержание статьи и добавляем её внутрь обёртки
    $('.kc__wrap').clone().appendTo('#widget-wrap-content-list');

    // Счищаем ненужную обёртку
    $(".contents", '#widget-wrap-content-list').unwrap();

    // Добавляем ссылку для прокрутки вверх
    $('.content-list-title', '#widget-wrap-content-list').append('<div style="float:right" data-pr="↑ Наверх ↑" class="link gototop"></div>');

    // При клике по gototop прокручиваем вверх
    $('.gototop', '.content-list-title').on('click', function () {
        $("html, body").animate({
            'scrollTop': 0
        }, 600);
    });

    var // Объявляем переменные
    $l = $('#post-content-list'), // Контейнер виджета дубля содержания страницы

        $ot = $l.offset().top, // Координаты верха виджета, $PostContentListOffsetTop

        $lh = $l.outerHeight(true), // Высота виджета меню, $PostContentListHeight

        $p = $('.post'), // Контейнер поста

        $w = $(window); // Контейнер главного окна 

    // Если содержание не помещается в окно, удаляем его 
    if ( $lh > $w.height() ) $l.remove();

    // Обрабатываем событие скролла 
    $w.on('scroll', function () { //console.log($('.post').height(), " ",  eval($('#post-content-list').offset().top + $lh));

        // Высота статьи
        var $ph = $p.height();

        // Координаты скролла по вертикали
        var $wst = $w.scrollTop();

        // Если прошли ниже, чем макушка виджета меню...
        if ($wst > $ot &&

        // ...и если не достигли конца статьи
        $ph > $wst + $lh) {

            $l.css({
                "position": "fixed",
                    "top": 0,
                    "width": "360px"
            }).fadeIn();

        }

        // Когда дошли до конца статьи, скрываем содержание статьи 
        else if ($ph < $wst + $lh) {

            $l.fadeOut();
        }

        // Иначе убираем фиксацию
        else {

            $l.css({
                "position": "relative",
                    "top": 0,
                    "width": "360px"
            }).fadeIn();

        }

    });

}
});

В заключение

Если вам понравилась статья, но что-то не получается переделать под свои нужды, не стесняйтесь спрашивать об этом в комментариях, вместе найдём решение.



Так себеНеплохоНормальноХорошоОтлично (8 оценок, в среднем: 4,63 из 5)
Загрузка...


  • Как выровнять css position absolute по центру
  • Как обнаружить и обойти Adblock и другие блокировщики рекламы
  • Репостинг на страницу Facebook из WordPress
  • Вебмастер Яндекс — Оригинальные Тексты и WordPress
  • РСЯ — контекстная реклама Яндекса на сайте

Вебразработка jQuery

Фиксированные меню, блоки при прокрутке страницы

Свежие записи

  • Squid — свой собственный HTTP Proxy сервер
  • Как исправить ошибку «Обновить WordPress — В настоящий момент выполняется другое обновление»
  • Query Monitor
  • LEMP
  • Telegram

Свежие записи

  • Squid — свой собственный HTTP Proxy сервер
  • Как исправить ошибку «Обновить WordPress — В настоящий момент выполняется другое обновление»
  • Query Monitor
  • LEMP
  • Telegram

Свежие комментарии

  • Sheens к записи Что такое SSL и TLS, как установить и настроить
  • Геомант к записи Что такое SSL и TLS, как установить и настроить
  • Sheens к записи Last-Modified в WordPress
  • Артур к записи Last-Modified в WordPress
  • Sheens к записи EWWW Image Optimizer — плагин для сжатия png, jpeg, gif анимации без потери качества
  • Telegram
  • Вконтакте
  • Facebook
  • Twitter
  • Google+
  • Одноклассники
  • Мой Мир Mail.ru
  • RSS

Copyright © 2025 · Sheensay on Genesis Framework · WordPress · Log in