Мобильная
версия

Фиксированная правая колонка

Дата: Категория: JavaScript

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

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

Сейчас все чаще встречаются решение либо привязать эту колонку к верху страницы (CSS - position:finxed; top:0px), либо, если есть какая-то красивая шапка, решение на JS - во время скролла страницы колонка привязывается к верху только если ее верхняя часть уходит за пределы экрана.

Очень даже неплохое решение, и достаточно простое.

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

В этой статье я расскажу вам как реализовал правую колонку в своем блоге (вы сможете увидеть ее в действии прямо сейчас проскролив страницу).
На идею меня натолкнул новостной сайт mail.ru. Если вы выберет какую либо новость, то увидите что там колонка двигается точно также как и у меня в блоге.

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

Чтож, идея есть - приступим к написанию кода.

Для начала определим константы

// сама колонка
    var el = $('#column');
// высота подвала (чтобы при прокрутке вниз колонка не заезжала на него)
    var max_down = $('#footer').outerHeight(true);

    var doc = $(document);
    var win = $(window);
// позиция элемента от верха экрана
    var el_top = el.offset().top;
// запомним все необходимые свойства элемента
    var main_position = {
        'position': el.css('position'),
        'top': el.css('top'),
        'left': el.css('left')
    }

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

// задаем начальное позиционированние элементу
    el.css({
        'position': 'absolute',
        'top': el_top + 'px',
        'left': el.offset().left + 'px'
    });
И определяем условия при которых наш скрипт будет работать.
Если высота документа меньше высоты правой колонки, то ничего с ней делать не нужно - оставляем как есть.
// только в случае если высота документа больше чем высота правой колонки
if(doc.height() - max_down > el_top + el.height()) {
/*
* Весь наш будущий код.
*/
} else {
// если высота документа меньше правой колонки то присваиваем ему старый css
    el.css(main_position);
}
Так как мы уже присвоили элементу абсолютное позиционирование (для того чтобы убрать погрешность в расчетах высоты при высоте колонки больше высоты документа), задаем колонке те параметры которые были запомнены в самом начале.

Подготовка завершена.

Первое что нужно сделать это написать маленькую функцию которая будет определять куда именно пользователь прокрутил страницу - вверх или вниз.

var up_down = 0;
function is_down() {
    var is_down = doc.scrollTop() > up_down;
    up_down = doc.scrollTop();
    return is_down;
}
Тут идет проверка - если высота до верха документа больше чем прошлая высота (по умолчанию 0) то пользователь скролит вниз.Если нет - вверх. 
После изменяем старое значение высоты и задаем ему текущее для проверки в следующий раз.

Хорошо, идем дальше.

Следующее что нужно сделать это определить доскролил ли пользователь до элемента (например если он расположен ниже шапки)

if (doc.scrollTop() >= el_top) {
/*
* Весь наш будущий код 
*/
} else {
// если до верха элемента недоскролили
    el.css({
        'position': 'absolute',
        'top': el_top + 'px'
    });
}

Если пользователь не доскролил до элемента или перескролил его (например перешел к самому верху страницы), то задаем элементу его стартовую позицию.

А теперь самое интересное - вначале теория.
1 - скролл вниз.

  • Если нижняя граница колонки находится выше чем нижняя граница экрана то осуществляем привязку
  • Если высота колонки меньше высоты рабочего пространства (экрана) то просто привязываем ее к верху страницы
  • И нельзя позволять нашей колонки опускаться ниже максимальной высоты (высоты элемента #footer)

Эта часть кода тоже не сложная, и хорошо прокомментирована.

// если нижняя граница элемента выше чем нижняя граница экрана
if (el.offset().top + el.height() < doc.scrollTop() + win.height()) {
// определяем высоту ниже которой нельзя опускать
    var max_top = doc.height() - max_down - el.height();
// если элемент меньше экрана пользвоателя
// то просто привязываем его к верху страницы
    if (win.height() > el.height()) {
        var top = doc.scrollTop();
    } else {
        var top = doc.scrollTop() - (el.height() - win.height());
    }
// если высота ниже максимальной
    if (top > max_top) { 
        top = max_top;
    }
    el.css({
        'position': 'absolute',
        'bottom': '',
        'top': top + 'px'
    });
}

И остается у нас только что делать если пользователь скролит вверх.
Тут все еще проще - всего лишь нужно, если верхняя граница экрана выше чем позиция элементы сверху, задать ему расстояние сверху равное верхней границе экрана.

// если высота проскролености меньше верха элементка
if (doc.scrollTop() < el.offset().top) {
    el.css({
        'position': 'absolute',
        'bottom': '',
        'top': doc.scrollTop() + 'px'
    });
}
Вот и все - таким нехитрым кодом мы получили очень красивую и удобную правую колонку.

Весь выложенный код можно посмотреть на github

Надеюсь вам было интересно прочитать, и возможно даже позаимствовать мои наработки.

Теги: #JavaScript, #jQuery

Ваша оценка:

Рейтинг: 9.8 (Оценок: 3)

Комментарий:

Copyright © DOC_tr 2015-2017 г. Все права защищены
Яндекс.Метрика
Перейти к мобильной версии