Меню
Обсудить сайт

Прогресс-бар за 20 строк.

Сегодня будем делать прогресс-бар. Он может помочь вашим пользователем понять, много ли осталось читать.

Все вместе решение занимает 20 строк. Демо на codepen.

Демо здесь:

Раз

Создаем HTML разметку:

 <div class="line" id="line"></div>

Добавили класс для оформления и id для связки с js.

Два

Накинем немного css оформления:

.line {
   width: 0;
   background-color: yellow;
   height: 5px;
   position: fixed;
   left: 0;
   top: 0;
   transition: .3s all;
}

body {
   min-height: 1000px;
   background-color: #333;
}

Линию сделали фиксированной с нулевой шириной и высотой в 5px, сделали желтый фон. body сделали минимальную высоту для проверки, чтобы не набивать бестолковым контентом. Сделали темный фон.

Если изменить ширину в css, мы увидим вот такую картину:

Прогресс-бар за 20 строк. 1
Линия и темный body

Отлично, все работает как и планировалось.

Три

Прежде чем писать код нам ответить себе на 2 вопроса:

  1. Какие данные нам нужны?
  2. Когда будет обновляться линия

Какие данные нужны: высота браузера, высота документа, отступ от верха страницы.

Когда будет обновляться линия: при прокрутке и еще при посещении. Браузер умеет запоминать положение пользователя после обновления страницы, так что к этому нужно быть готовым.

Так как обновление будет происходить в нескольких местах, а код будет одинаковый, создадим функцию lineWidthSet (), но прежде объявим несколько переменных:

var line = document.querySelector('#line'),
    bodyHeight = document.body.clientHeight,
    doc = document.documentElement;

Line — наша линия,
bodyHeight — высота body,
doc — корневой элемент документа, нужен нам для расчета отступа от верха.

Теперь приступим к написанию функции lineWidthSet ():

  1. Получаем отступ от верха страницы.
  2. Прибавляем к нему высоту окна браузера.
  3. Высчитываем процентное соотношение позиции от высоты страницы.
  4. Устанавливаем ширину линии.

(2) Почему мы прибавляем высоту браузера?. Когда вы на находитесь на странице, вы уже видите то, что в области окна вашего браузера, то есть вы уже это прочитали.

В соответствии с списком действий, пишем функцию:

function setWidthLine() {
   var scrollTop = (window.pageYOffset || doc.scrollTop)  - (doc.clientTop || 0) // (1),
       percent;
   scrollTop += doc.clientHeight; //(2)
   
   percent = scrollTop / bodyHeight * 100; //(3)
   line.style.width = percent + '%'; //(4)
}

(1) Здесь мы используем несколько проверок, для кроссбраузерности. Получили отступ от верха страницы.

(2) Добавили высоту окна браузера

(3) Рассчитали по формуле процентное соотношение и конкатенировали знак «%» для указания того, что это проценты.

(4) Установили ширину линии

Теперь нужно эту функцию вызывать при 3 событиях: загрузка, прокрутка, изменение ширины браузера. С загрузкой все понятно, просто вызываем функцию без каких-либо событий (1), а для прокрутки добавляем событие (2):

setWidthLine();

document.addEventListener('scroll', function() {
   setWidthLine();
});

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

document.addEventListener('resize', function() {
   setWidthLine();
});

Все вместе:

HTML:

<div class="line" id="line"></div>

CSS:

.line {
   width: 0;
   background-color: yellow;
   height: 5px;
   position: fixed;
   left: 0;
   top: 0;
   transition: .3s all;
}

body {
   min-height: 1000px;
   background-color: #333;
}

Javascript:

var line = document.querySelector('#line'),
    bodyHeight = document.body.clientHeight,
    doc = document.documentElement;

setWidthLine();

document.addEventListener('scroll', function() {
   setWidthLine();
});

document.addEventListener('resize', function() {
   setWidthLine();
});

function setWidthLine() {
   var scrollTop = (window.pageYOffset || doc.scrollTop)  - (doc.clientTop || 0),
       percent;
   scrollTop += doc.clientHeight;
   
   percent = scrollTop / bodyHeight * 100;
   line.style.width = percent + '%';
}

Есть вопросы, замечания — в комментарии.

Поделиться
Отправить

Комментарии