Элемент progress
При разработке сайтов и веб-приложений часто появляется необходимость информировать пользователя о процессе выполнения его запроса или задачи: загрузки файла, проигрывания видео или импортирования данных.
В HTML5 описан элемент, который должен упростить нам жизнь: элемент <progress>
,
единственная задача которого как раз и состоит в отображении прогресса
выполнения задачи.
Лучше всего он описан в спецификации HTML5:
Элемент
<progress>
представляет прогресс выполнения задачи.
Сама задача на данный момент нас не интересует, в отличии от отображения хода её выполнения.
Атрибуты
Для элемента <progress>
в спецификации обозначены четыре атрибута: max
,
value
, position
и label
. Перед тем как приступить к поочерёдному разбору
этих атрибутов, несколько важных примечаний о них:
- если указан атрибут
value
, индикатор прогресса считается определённым (т.е. у него есть чёткие предельные значения). В противном случае он считается неопределённым. - Если атрибут
max
не указан, по умолчанию диапазон допустимых значений для индикатора прогресса будет между 0.0 и 1.0 включительно. - Желательно всегда добавлять текущее значение и максимальное значение (если они
используются) в виде встроенного текста в элементе
<progress>
чтобы пользователи старых версий браузеров тоже их увидели.
А сейчас давайте более внимательно рассмотрим каждый атрибут:
Max
Атрибут max
— это число с плавающей запятой, которое обозначает какой объем
работы должен быть выполнен в общем для завершения задачи. Значение по умолчанию — 1.0.
Value
Это число с плавающей запятой, которое представляет текущий прогресс выполнения
задачи. Его значение должно быть больше или равно 0.0 и меньше или равно 1.0
или меньше или равно значению атрибута max
, если он указан.
Position
Этот атрибут доступен только для считывания. Он возвращает текущее состояние
элемента <progress>
. Его значение равно значению атрибута value
деленному
на значение атрибута max
для определённого индикатора прогресса и -1
для
неопределённого индикатора прогресса (так как текущее состояние не может быть
рассчитано точно).
Label
Этот атрибут также доступен только для считывания, он возвращает список меток
label
для элемента <progress>
(если они есть в наличии).
Примеры
Теперь давайте рассмотрим примеры применения элемента <progress>
, а также как
его можно обновлять с помощью JavaScript.
Простой неопределённый индикатор прогресса
<progress id='p'></progress>
Поскольку мы понятия не имеем сколько времени потребуется на выполнение задачи, браузер просто будет отображать индикатор прогресса пока задача не будет завершена и мы не спрячем индикатор прогресса, либо не заменим его сообщением «задача выполнена».
Простой определённый индикатор прогресса
<progress id='p' max='70'><span>0</span>%</progress>
И JavaScript для его обновления:
var pBar = document.getElementById('p');
var updateProgress = function(value) {
pBar.value = value;
pBar.getElementsByTagName('span')[0].innerHTML = Math.floor((100 / 70) * value);
}
Обратите внимание, что в этом примере 70 — это максимальное значение которое
может принимать индикатор прогресса, потому обращение к updateProgress
будет
иметь значение между 0 и 70. Кроме того, значение также отображается в элементе
<progress>
как простая строка с процентами для пользователей старых версий
браузеров.
Использование <progress>
с видео в HTML5
Хорошим примером использования элемента <progress>
служит видео в HTML5, где
индикатор прогресса информирует пользователя о том, какая часть видео уже
произведена. Я не буду приводить весь код, только необходимую часть HTML и
JavaScript.
У нас есть элемент <video>
с «v» в качестве id
.
<progress id='p' max='100' value='0'><span>0</span>% проиграно</progress>
Используйте следующий JavaScript:
var video = document.getElementById('v');
var pBar = document.getElementById('p');
video.addEventListener('timeupdate', function() {
var percent = Math.floor((100 / video.duration) * video.currentTime);
pBar.value = percent;
pBar.getElementsByTagName('span')[0].innerHTML = percent;
}, false);
В JavaScript используется событие timeupdate
, которое постоянно инициируется в
процессе проигрывания видео. Значение конвертируется в процентное число на
основе duration
(полная длина) и currentTime
(текущая точка в видео).
Использование <progress>
для File API
Ещё один полезный пример: использование элемента <progress>
для File API.
Опять же, в примере не полный код, он предполагает наличие формы для загрузки
файла и кнопки «загрузить», элемента <progress>
и кода для чтения файла.
Непосредственно в самой спецификации есть неплохие примеры.
var p = document.getElementById('p');
reader.addEventListener('loadstart', function(evt) {
if (evt.lengthComputable) p.max = evt.total;
}, false);
reader.addEventListener('progress', function(evt) {
if (evt.lengthComputable) p.value = evt.loaded;
}, false);
Здесь событие loadstart
используется чтобы задать атрибут max
для элемента
<progress>
, затем с помощью события progress
обновляется атрибут value
для
элемента <progress>
.
Поддержка браузерами
На сегодняшний день элемент <progress>
довольно неплохо поддерживается
большинством браузеров. Только в Safari он поддерживается с версии 6+ (что
исключает Safari под Windows, так как для него пока только версия 5.1) и в
версии 10+ в Internet Explorer.
Стилизация
Как и для других элементов такого типа, у каждого браузера есть свой вариант
стилизации для элемента <progress>
. Вы, однако, можете в некоторой степени
изменить её, используя несложный CSS.
Как правило, стиль по умолчанию предполагает элемент со скругленными уголками, серым фоном и зеленым градиентом собственно для шкалы прогресса.
Стилизация элемента <progress>
по умолчанию в Firefox 18.0.2.
Представим что нам нужно стилизировать индикатор прогресса для сайта HTML5 Doctor, так чтобы он вписывался в дизайн сайта. Удалим эффект выпуклости и градиенты, будем использовать сплошную заливку:
progress {
color: #0063a6;
font-size: .6em;
line-height: 1.5em;
text-indent: .5em;
width: 15em;
height: 1.8em;
border: 1px solid #0063a6;
background: #fff;
}
Он, однако, не поможет изменить цвет самого индикатора прогресса, который останется зеленым. Это можно изменить в Firefox, Internet Explorer 10, Chrome и Safari с помощью различных методов, описанных ниже.
Firefox
Всё что нужно добавить это:
progress::-moz-progress-bar { background: #0063a6; }
и в Firefox будет отображаться нужный нам цвет.
Вид индикатора прогресса в Firefox 18.0.2 после дополнительной стилизации.
Chrome и Safari
Для Chrome и Safari следует использовать progress::-webkit-progress-value
чтобы указать цвет индикатора прогресса и progress::-webkit-progress-bar
чтобы
изменить фоновый цвет самого элемента <progress>
.
progress::-webkit-progress-bar { background: #fff; }
progress::-webkit-progress-value { background: #0063a6; }
Обновление, добавлено 13 февраля, 2013 года
Разработчики Opera только что объявили о переходе на движок WebKit, так что в конце концов правила стилизации WebKit будут работать и в Opera тоже.
Internet Explorer 10
Вообще то приведённого выше кода CSS будет достаточно чтобы задать стиль для
элемента <progress>
в IE10, но нужно отметить что этот браузер под цветом
элемента <progress>
понимает цвет индикатора прогресса.
Я загрузил несколько рабочих примеров определённых и неопределённых индикаторов прогресса чтобы вы могли на них взглянуть.
Итог
Элемент <progress>
может показаться очень похожим на элемент <meter>
,
который также был введён в HTML5, но его можно считать более
узкоспециализированным вариантом этого элемента, который используется только
для отображения прогресса выполнения задачи. Это стоит помнить когда придётся
выбирать между ними.
Учитывая хорошую поддержку браузерами, в подходящих случаях определённо стоит
использовать элемент <progress>
, но нужно обеспечить текстовый резервный
контент для старых версий браузеров.