Плавающий блок (меню) при прокрутке страницы на jquery
- Категория: Код
- – Автор: Игорь (Администратор)
На сайтах, состоящих из нескольких колонок, часто встречается проблема пустого пространства при прокрутке страницы вниз. Когда после определенного момента скриллинга в одной из колонок образуется свободное место, которое смотрится некрасиво. Например, когда текст страницы вдвое, а то и втрое, превышает размеры колонок. Существует, как минимум, три возможных варианта решения этой проблемы. Во-первых, если колонка помещается на экране страницы (даже в тот момент, когда вы достигли футера), то ее можно просто зафиксировать css стилями. Во-вторых, если тексты на сайте примерно одинаковой длины, то колонку можно наполнить блоками до необходимого размера. И в-третьих, можно сделать последний блок или меню плавающим при прокрутке страницы на jquery (JavaScript).
В данной статье речь пойдет о третьем варианте, как о самом распространенном. А вот пример проблемы:
Отслеживаем события window scroll (для прокрутки) и resize (для изменения высоты)
Из всего набора событий активного окна window интересуют только два - window scroll и window resize. Необходимо учитывать оба события, так как позиция блока должна корректироваться не только при скроллинге (прокрутке страницы), но и в том случае, если пользователь будет изменять размер окна, например, растягивать или уменьшать по высоте, как показано на рисунке ниже. В противном случае, плавающий блок может залезть на область футера.
Оба этих события легко отслеживаются JavaScript-ом, так что особых проблем с этим не возникнет. Кроме того, учтите, что если при изменении размера активного окна будет меняться разметка или расположение блоков, например, сжиматься ширина блока с текстом (например, на этом сайте есть два варианта ширины области контента для 1024 и для 1280+), то высота документа будет изменяться, из-за чего необходимо пересчитывать положение блока.
Делаем html заготовку с двумя колонками и добавляем блоки в сайдбар
Прежде всего создадим небольшую html-заготовку из двух файлов index.html и template.css.
Примечание: В рамках рассмотрения не приводится набор стилей и полный код html, так как они не представляют особого интереса. Тем не менее, весь проект доступен в архиве по ссылке в конце статьи.
Первое, что нам понадобиться - это подключить jQuery c CDN:
Затем набросать разметку страницы:
И наполнить их данными:
Должна получиться примерно следующая страница:
Как видите заготовка достаточно наглядно демонстрирует проблему свободного пространства при прокрутке.
Теперь, можно приступать к написанию кода.
Пишем скрипт плавающего блока (меню) на jquery
Скрипт плавающего блока или меню на jquery состоит из нескольких частей.
Во-первых, кроссбраузерная функция для добавления обработчиков window scroll и window resize.
Во-вторых, сама функция обработчик изменения положения плавающего блока (меню):
Несколько пояснений к функции. Расчет положения плавающего блока должен идти в зависимости от размера всех соседних блоков в колонке, так как если их высота изменится во время прокрутки (скроллинга), например, загрузятся картинки, то запоминание стартовой позиции приведет к тому, что плавающий блок при возвращении на начальную позицию начнет залезать на предыдущий блок, что не правильно. Так же, если использовать "position: absolute" (абсолютное позиционирования) вместо "position: fixed" (фиксированное позиционирование), то возможно возникновение эффекта "мерцания" блока из-за необходимости перерисовки элементов. Поэтому лучше всего использовать "position: fixed", в таком случае мерцания не будет.
И в-третьих, остается только повесить функцию на события scroll и resize.
Функцию updateColumnPosition необходимо вызвать не только по возникновению событий, но и сразу после загрузки dom-элементов, так как при обновлении страницы с помощью клавиши "F5", ни одно из событий не вызовется, а страница может быть уже прокручена вниз.
Собрав вместе все части и html-заготовку, получим плавающий блок, который будет останавливаться прямо перед футером, как показано на картинке:
Как видите, получилось достаточно простое решение, которое легко адаптировать под многие сайты, просто заменив селекторы у jQuery.
Теперь, у вас под рукой всегда будет код для создания плавающего блока или меню.
Скачать проект можно по ссылке:
☕ Понравился обзор? Поделитесь с друзьями!
Комментарии / отзывы
Подскажите пожалуйста, как плавающему блоку сделать анимацию, чтобы он плавно "плавал", когда страница до него доходит?
После блока
-----------------------------
// Добавляем все высоты остальных блоков
element.parent().find('.sidebar-block:not(:last)') .each(function () {
topHeight += jQuery(this).outerHeight();
});
-----------------------------
Заменить все до конца функции вот этим
-----------------------------
var save_scroll = element.data('save-scroll')
;
if (isNaN(save_scroll)) {
save_scroll = 0;
}
if (Math.abs(save_scroll - scrollTop) < 20) {
return;
}
// Если необходимо фиксировать блок сверху, и он не залезет на футер,
// то меняем его положение
if (scrollTop - topHeight > 20 && documentHeight - scrollTop - 40 > elementHeight + footerHeight) {
element.stop(true, true).css({position: 'fixed', top: (save_scroll - scrollTop) }).animate({
top: (20) + 'px'
},500, 'linear', function () {
element.data('save-scroll', scrollTop);
});
}
// Если блок нужно фиксировать, но элемент залезет на футер,
// то высставляем его положение на максимально возможное удаление от начала страницы
// (т.е. прижимаем к футеру)
else if (scrollTop - topHeight > 20 && documentHeight - scrollTop - 40 < elementHeight + footerHeight) {
element.stop(true, true).css({position: 'fixed', top: element.css('top') }).animate({
top: ((documentHeight - elementHeight - footerHeight - 20) - scrollTop) + 'px'
},500, 'linear', function () {
element.data('save-scroll', scrollTop);
});
}
// Если скрол не превысил границу для фиксации блока,
// то возвращаем ему его значения
else if (scrollTop - topHeight < 20) {
element.stop(true, true).animate({
top: '0px'
},500, 'linear', function () {
element.css({position: 'relative', top: '0px'});
element.data('save-scroll', scrollTop);
});
}
-----------------------------
Такой вопрос: если я знаю конкретную высоту .sidebar-block:last (т.к. вставила туда изображение), как правильно ее прописать в данном коде?
Спасибо!
Код вычисляет высоту динамически, вам не нужно указывать высоту картинки.
Заранее благодарю!
Находите строчку
Цитата: и меняете ее на
Цитата: