Когда я разрабатывал вторую версию шаблона для своего блога я хотел дать ему какую-то изюминку. Еще в то время я активно читал Medium. Я заметил, что у них интересным образом сделана шапка. Когда вы скроллите вниз, она прячется, продолжая скроллить вниз она все еще скрыта и как только начинаете двигаться вверх, она снова показывается. Я решил сделать такую же шапку (ну, почти) у себя в блоге.
Мне понравился подход Medium и я примерно понимал почему они выбрали именно такой способ относительно обычного фиксированной шапки сверху.
Вот несколько причин:
Первая — когда пользователь захочет вернуться к меню, оно у него сразу же появится как только он двинется чуть вверх.
Вторая — вы не загораживаете контент сайта — это самое дорогое и важное что у вас есть.
Третья — это придает изюминку сайту и выглядит интересно.
Демо
21516
Немного поразмыслив
Немного посмотреть на их концепцию, я решил ее чуть изменить.
У меня в заголовке был логотип и поиск в одну строчку и потом ними меню с 4-5 пунктами (пункты могут расти, в зависимости от того, что я добавляю).
И далее я понял, что я не хочу скрывать всю шапку, а лишь логотип и поиск, то есть меню всегда будет доступно сверху, если оно понадобиться зашедшему.
План
Абстрактно, шапка выглядит следующим образом:
Кратко: зона «Лого и Поиск» будет скрыта, меню останется.
Далее я обдумал как это сделать и решил, что:
- шапка будет фиксированной, чтобы она по умолчанию двигалась за пользователем
- как только она доходит до определенной точки от верха страницы — зона «Лого и Поиск» должна скрываться, «Меню» оставаться
- если пользователь продолжает скроллить ниже, то «Лого и Поиск» остается скрытой, «Меню» показывается
- если в определенный момент пользователь решил подняться вверх, вся шапка должна вернуться в изначальное положение
- все должно быть анимированным, не дергаться, чтобы не пугать пользователя
Код
HTML & CSS здесь особой роли не играет. Самое важное выполняет jQuery.
Для простоты работы я выбрал jQuery.
Полный скрипт:
$(document).ready(function() { var body = $(".container"); var header = $("header"); var nav = header.find("nav"); var max = 400; var headerHeight = header.outerHeight(); var navHeight = nav.outerHeight(); header.addClass('shown'); body.css("margin-top", headerHeight + 30); var lastActive = 0; $(window).on("scroll", function() { var top = $(document).scrollTop(); if (top >= max) { if(lastActive > мне нужно top) { header.removeClass('hidden'); header.addClass("shown"); header.stop().animate({ marginTop: 0 }, 200); } else { header.removeClass('hidden'); header.addClass("shown"); header.stop().animate({ marginTop: -(headerHeight - navHeight) }, 200); } lastActive = top; } else { if (header.hasClass('shown')) { header.removeClass('shown'); header.addClass("hidden"); header.stop().animate({ marginTop: 0 }, 200); } } }); });
Не пугайтесь, сейчас все объясню.
Изначально ожидаем загрузки DOM страницы, чтобы начать с ним работать с $(document).ready
.
Далее нужно обозначить часто используемые переменные. Вот их значения:
body
— это ваш контейнер, в моем случае — это где я отображаю текст страницы или статью (которую вы читаете сейчас). Требуется для того, чтобы сделать отступ от шапкиheader
— это главной элемент шапки — наш главной геройnav
— элемент внутри шапки, отвечающий за отображение меню (если оно у вас есть)max
— это максимальная высота сверху от страницы после которой будет скрыта шапка до меню. Допустим, вы проскроллили 400 пикселей вниз и какая-то логика после этого должна произойти.headerHeight
— это высота элементаheader
(шапки)navHeight
— это высота меню
Вероятнее всего вам нужно будет заменить некоторые селекторы на свои. Одно решение для каждого создать нельзя, так как это зависит от сайта к сайту.
Далее нужно поставить значения по умолчанию:
header.addClass('shown'); body.css("margin-top", headerHeight + 30); var lastActive = 0;
Для шапки добавим класс shown
, чтобы означает показана, для body
установим верхний отступ, чтобы был отступ от шапки (размер шапки + 30 пикселей.
Далее немного магии:
$(window).on("scroll", function() { var top = $(document).scrollTop(); if (top >= max) { if(lastActive > top) { header.removeClass('hidden'); header.addClass("shown"); header.stop().animate({ marginTop: 0 }, 200); } else { header.removeClass('hidden'); header.addClass("shown"); header.stop().animate({ marginTop: -(headerHeight - navHeight) }, 200); } lastActive = top; } else { if (header.hasClass('shown')) { header.removeClass('shown'); header.addClass("hidden"); header.stop().animate({ marginTop: 0 }, 200); } } });
$(window).on("scroll")
означает, что мы заинтересованы в событии скроллинга. И уже внутри, мы может выполнять нашу логику.
В самом верху, есть переменная top
, которая будет записывать текущую высоту сверху страницы каждый раз когда пользователь скролл.
Далее у нас есть условие if
, else
.
Скрытие/отображение (if)
В if
я проверяю не является ли текущая высота больше той, которую мы определили в max
. Если является, то нужно спрятать шапку по меню.
Если обратить внимание, то внутри есть еще условие, которые проверяет не прокрутил ли пользователь вверх когда он уже ниже max
. Если не ушел, то сработает else
:
} else { header.removeClass('hidden'); header.addClass("shown"); header.stop().animate({ marginTop: -(headerHeight - navHeight) }, 200); }
Я использовал метод animate()
, которые позволяет анимировать действия. в данном случае, я менял CSS свойство margin-top
. Я поставил минусовой маргин, который равен:
высота шапки — минус высота меню
Таким образом у нас получается высота по меню и не больше.
Если вы не ушли за max
значит сработает это условие:
if(lastActive > top) { header.removeClass('hidden'); header.addClass("shown"); header.stop().animate({ marginTop: 0 }, 200);
Для проверки двигается пользователь вверх или вниз — используется переменная lastActive
, которая записывается предыдущее значение высоты когда пользователь находится ниже max
высоты.
Отображение (else)
В случае когда пользователь находится выше max
, нужно показать шапку.
Для WordPress
Если вам нужно вставить данные код в WordPress, сделайте это следующим образом:
- откройте functions.php
- и укажите код ниже:
function smart_header() { ?> <script> {JS КОД} </script> <?php } add_action('wp_footer', 'smart_header');
- Замените
{JS КОД}
на JavaScript код, на полный код, который я указывал выше в этом посте
Вывод
Как видите все не так сложно, главное немного поразмыслить над реализацией, а уже сам процесс дастся легко, если вам это интересно.
Если у вас возникнут какие-либо вопросы — пишите ниже, буду раз помочь.