- Автор: Чен большая голова
- гитхаб:KRISACHAN
Индикатор выполнения — очень распространенная функция, ее несложно реализовать, обычно мы будем использоватьdiv
реализовать.
Как такое общее требование,whatwgНативного компонента точно не предусмотрено (хотя мы можем его и не использовать), так что давайте посмотрим, какие интересные реализации прогресс-бара есть у Kangkang.
Обычная версия — div flow
Это более обычная реализация, сначала посмотрите на эффект:
Исходный код выглядит следующим образом:
<style>
.progress1 {
height: 20px;
width: 300px;
background-color: #f5f5f5;
border-bottom-right-radius: 10px;
border-top-right-radius: 10px;
}
.progress1::before {
counter-reset: progress var(--percent, 0);
content: counter(progress) '%\2002';
display: block;
height: 20px;
line-height: 20px;
width: calc(300px * var(--percent, 0) / 100);
font-size: 12px;
color: #fff;
background-color: #2486ff;
text-align: right;
white-space: nowrap;
overflow: hidden;
border-bottom-right-radius: 10px;
border-top-right-radius: 10px;
}
.btn {
margin-top: 30px;
}
</style>
<div id="progress1" class="progress1"></div>
<button id="btn" class="btn">点我一下嘛~</button>
<script>
'use strict';
let startTimestamp = (new Date()).getTime();
let currentPercentage = 0;
let maxPercentage = 100;
let countDelay = 100;
let timer = null;
let start = false;
const percentageChange = () => {
const currentTimestamp = (new Date()).getTime();
if (currentTimestamp - startTimestamp >= countDelay) {
currentPercentage++;
startTimestamp = (new Date()).getTime();
progress1.style = `--percent: ${currentPercentage}`;
};
if (currentPercentage < maxPercentage) {
timer = window.requestAnimationFrame(percentageChange);
} else {
window.cancelAnimationFrame(timer);
};
};
const clickHander = () => {
if (!start) {
start = true;
percentageChange();
};
};
btn.addEventListener('click', clickHander);
</script>
Суть этого метода заключается в использовании текущего блока в качестве контейнера для::before
Наполните его содержанием. использовать<div>
Преимущество в том, что реализация проста, совместимость надежна и масштабируемость высока, но ложка дегтя в том, что семантика меток не сильна.
Дополнительно — тип ввода="диапазон"
<input />
очень полезный сменный элемент, отличающийсяtypeможет делать разные вещи. Второй заключается в использовании<input type="range" />
быть реализованным. Сначала давайте посмотрим на эффект:
Исходный код выглядит следующим образом:
<style>
.progress2[type='range'] {
display: block;
font: inherit;
height: 20px;
width: 300px;
pointer-events: none;
background-color: linear-gradient(to right, #2376b7 100%, #FFF 0%);
}
.progress2[type='range'],
.progress2[type='range']::-webkit-slider-thumb {
-webkit-appearance: none;
};
.progress2[type='range']::-webkit-slider-runnable-track {
border: none;
border-bottom-right-radius: 10px;
border-top-right-radius: 10px;
height: 20px;
width: 300px;
}
.btn {
margin-top: 30px;
}
</style>
<input id="progress2" class="progress2" type='range' step="1" min="0" max="100" value="0"/>
<button id="btn" class="btn">点我一下嘛~</button>
<script>
'use strict';
let startTimestamp = (new Date()).getTime();
let currentPercentage = 0;
let maxPercentage = 100;
let countDelay = 100;
let timer = null;
let start = false;
let percentageGap = 10;
const percentageChange = () => {
const currentTimestamp = (new Date()).getTime();
if (currentTimestamp - startTimestamp >= countDelay) {
currentPercentage++;
startTimestamp = (new Date()).getTime();
progress2.value = currentPercentage;
progress2.style.background = `linear-gradient(to right, #2376b7 ${currentPercentage}%, #FFF 0%`;
};
if (currentPercentage < maxPercentage) {
timer = window.requestAnimationFrame(percentageChange);
} else {
window.cancelAnimationFrame(timer);
};
};
const clickHander = () => {
if (!start) {
start = true;
percentageChange();
};
};
btn.addEventListener('click', clickHander);
</script>
После написания этой демонстрации я узнал,<input type="range" />
Не подходит для этой функции. . Одной из них является сложность реализации, этоtypeКаждый элемент компонента можно стилизовать индивидуально, но эффект будет не очень.
Другое дело, потому чтоrangeУ него есть своя семантика — область видимости, поэтому он больше подходит для того, чтобы делать что-то вроде этого:
Выше демо из:developer.Mozilla.org/en-US/docs/…
Премиум - утка прогресса
Конечно, вышеперечисленные два способа имитируют индикатор выполнения, на самом деле нам не нужно имитировать, потому чтоwhatwgДля нас предусмотрены собственные метки индикатора выполнения -<progress>
.
Давайте сначала посмотрим на эффект:
Реализация выглядит следующим образом:
<style>
.progress3 {
height: 20px;
width: 300px;
-webkit-appearance: none;
display: block;
}
.progress3::-webkit-progress-value {
background: linear-gradient(
-45deg,
transparent 33%,
rgba(0, 0, 0, .1) 33%,
rgba(0,0, 0, .1) 66%,
transparent 66%
),
linear-gradient(
to top,
rgba(255, 255, 255, .25),
rgba(0, 0, 0, .25)
),
linear-gradient(
to left,
#09c,
#f44);
border-radius: 2px;
background-size: 35px 20px, 100% 100%, 100% 100%;
}
.btn {
margin-top: 30px;
}
</style>
<progress id="progress3" class="progress3" max="100" value="0"></progress>
<button id="btn" class="btn">点我一下嘛~</button>
<script>
'use strict';
let startTimestamp = (new Date()).getTime();
let currentPercentage = 0;
let maxPercentage = 100;
let countDelay = 100;
let timer = null;
let start = false;
const percentageChange = () => {
const currentTimestamp = (new Date()).getTime();
if (currentTimestamp - startTimestamp >= countDelay) {
currentPercentage++;
startTimestamp = (new Date()).getTime();
progress3.setAttribute('value', currentPercentage);
};
if (currentPercentage < maxPercentage) {
timer = window.requestAnimationFrame(percentageChange);
} else {
window.cancelAnimationFrame(timer);
};
};
const clickHander = () => {
if (!start) {
start = true;
percentageChange();
};
};
btn.addEventListener('click', clickHander);
</script>
Нативная метка прогресс-бара хоть и есть, но конкретная ее производительность в спецификации не указана, поэтому каждый производитель браузера может настроить ее под свои предпочтения, а стиль совершенно неуправляемый, так что метка хорошая. . Юзабилити не сильное, а жаль.
Ultimate Edition — метр сайго
Конечно, метки, способные реализовать функцию индикатора выполнения, помимо вышеперечисленных, также существуют.<meter>
Этикетка. Первый взгляд на эффект:
код показывает, как показано ниже:
<style>
.progress4 {
display: block;
font: inherit;
height: 50px;
width: 300px;
pointer-events: none;
}
.btn {
margin-top: 30px;
}
</style>
<meter id="progress4" class="progress4" low="60" high="80" min="0" max="100" value="0"></meter>
<button id="btn" class="btn">点我一下嘛~</button>
<script>
'use strict';
let startTimestamp = (new Date()).getTime();
let currentPercentage = 0;
let maxPercentage = 100;
let countDelay = 100;
let timer = null;
let start = false;
const percentageChange = () => {
const currentTimestamp = (new Date()).getTime();
if (currentTimestamp - startTimestamp >= countDelay) {
currentPercentage++;
startTimestamp = (new Date()).getTime();
progress4.value = currentPercentage;
};
if (currentPercentage < maxPercentage) {
timer = window.requestAnimationFrame(percentageChange);
} else {
window.cancelAnimationFrame(timer);
};
};
const clickHander = () => {
if (!start) {
start = true;
percentageChange();
};
};
btn.addEventListener('click', clickHander);
</script>
Этот ярлык может быть незнакомым, на самом деле он связан с<input type="range">
Семантика та же и используется для отображения скалярных или дробных значений известного диапазона. Разница в том. . . Со стилем сложнее.
Суммировать
В этой статье оцениваются 4 способа реализации индикатора выполнения, и вывод таков:<div>
Пик сезона. . . Хотя иногда хочется провести семантику лейблов чуть изящнее, но ресурсы это не поддерживают, и это тоже очень смущает.
о, всемогущий<div>
.
Все приведенные выше демонстрации можно посмотреть на моей кодовой ручке:код спрей.IO/Антияпонское производство 77/…