Как сделать разный % у шкалы прогресса в JS
Всем привет.
Как при помощи JS задать разный % шкалы прогресса у каждого из навыков, при условии, что я хочу оставить один общий класс в HTML
.progress {
border-radius: 10px;
width: 150%;
height: 7px;
overflow: hidden;
background: linear-gradient(to right, #235F67,#40A0B0);
}
.grayback {
position: relative;
left: 92%; /* Текущее состояние */
width: 100%;
height: 100%;
background-color: #ddd;
}
<div class="progress">
<div class="grayback"></div>
</div>
Мне нужно, чтобы в grayback можно было изменять значение % left при помощи JS, чтобы у каждого навыка был свой процент, как реализовать код я немного не понимаю
Ответы (3 шт):
Элемент progress создан как раз для этого
<progress value="0.25"></progress> Она <br/>
<progress value="0.5"></progress> Её отец <br/>
<progress value="0.75"></progress> Её брат <br/>
<progress value="1"></progress> Парень, о котором она просит не беспокоится <br/>
<progress value="0"></progress> Я <br/>
Им можно управлять и с помощью js:
document.querySelectorAll(`progress`).forEach((element, index) => {
element.value = 1 / (index + 1);
});
<progress></progress><br/>
<progress></progress><br/>
<progress></progress><br/>
<progress></progress><br/>
<progress></progress><br/>
<progress></progress><br/>
<progress></progress><br/>
<progress></progress><br/>
<progress></progress><br/>
<progress></progress><br/>
Решение 1
Вообще можно сделать вот так:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background-color: rgb(90, 90, 90);
}
.progress {
background-color: rgb(255, 255, 255);
height: 6px;
border-radius: 16px;
overflow: hidden;
margin: 1em;
}
.progress-actual {
width: var(--progress);
background-image: linear-gradient(to right, rgb(35, 95, 103), rgb(62, 155, 170));
height: 100%;
}
<div class="progress">
<div class="progress-actual" style="--progress: 25%;"></div>
</div>
<div class="progress">
<div class="progress-actual" style="--progress: 50%;"></div>
</div>
<div class="progress">
<div class="progress-actual" style="--progress: 75%;"></div>
</div>
<div class="progress">
<div class="progress-actual" style="--progress: 100%;"></div>
</div>
Решение 2
Немного подумал и решил сократить решение используя псевдо элементы:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background-color: rgb(90, 90, 90);
}
.progress {
background-color: rgb(255, 255, 255);
height: 6px;
border-radius: 16px;
overflow: hidden;
margin: 1em;
}
.progress::before {
content: '';
width: var(--progress);
height: 100%;
display: block;
background-image: linear-gradient(to right, rgb(35, 95, 103), rgb(62, 155, 170));
}
<div class="progress" style="--progress: 25%;"></div>
<div class="progress" style="--progress: 50%;"></div>
<div class="progress" style="--progress: 75%;"></div>
<div class="progress" style="--progress: 100%;"></div>
Решение 3 (Продивинутое)
Так как у вас в метках указан javascript, решил также сделать удобную реализацию через JavaScript, вот так:
class Progress {
constructor(percentage) {
let _percentage = +percentage
percentage = _percentage && !isNaN(_percentage) ? _percentage : 0
let node = document.createElement('div')
node.className = 'progress'
node.setAttribute('style', `--progress: ${percentage}%;`)
node.dataset.progress = percentage
this.percentage = percentage
this.node = node
}
init(parentNode) {
let percentage = this.percentage
let node = this.node
setProgress(node, percentage)
if(parentNode) {
parentNode.appendChild(node)
}
return {
increase(n) {
let current = this.current()
setProgress(node, current + n)
},
decrease(n) {
let current = this.current()
setProgress(node, current - n)
},
current() {
return getProgress(node)
},
getNode() {
return node
}
}
function getProgress(_node) {
return +_node.dataset.progress
}
function setProgress(_node, progress) {
_node.setAttribute('style', '--progress:' + progress + '%;')
_node.dataset.progress = progress
}
}
}
let progressBar1 = new Progress(25)
.init(document.body)
let progressBar2 = new Progress(0)
.init(document.body)
progressBar2.increase(75) // Увеличить на 75
progressBar2.decrease(25) // Уменьшить на 25
let progressBar3 = new Progress(75)
.init()
console.log(progressBar3.current()) // Получить текущий процент в виде числа
let progressBar3Node = progressBar3.getNode() // Получить ноду (элемент) прогресс бара
if(progressBar3Node.tagName.toLowerCase === 'header') {
console.log('Hello!')
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background-color: rgb(90, 90, 90);
}
.progress {
background-color: rgb(255, 255, 255);
height: 6px;
border-radius: 16px;
overflow: hidden;
margin: 1em;
}
.progress::before {
content: '';
width: var(--progress);
height: 100%;
display: block;
background-image: linear-gradient(to right, rgb(35, 95, 103), rgb(62, 155, 170));
}
Как с этим работать?
В конструктор класса Progress первым (и единственным) аргументом приходит процент, можно вводить такие аргументы как: 42, "123", 42.42, "25.75", они все пробразуются в число (если аргумент не может быть преобразовон в число, вместо него будет использоваться 0), у класса есть метод init, в которым и происходит вся магия.
Первым (и также единственным) аргументом в init должен быть какой-то элемент, аргумент опциональный, если он существует, значит прогресс бар будет зааппенден в этот элемент, если его не существут значит элемент просто будет как есть.
Сам метод init, возвращает объект с такими функциями: increase, decrease, current и getNode. increase - принимает в себя один аргумент (число), на это число прибавляется текущий процент. decrease - принимает в себя один аргумент (число), на это число убавляется текущий процент. current - возвращает текущий процент. getNode - возвращает ноду (элемент) прогресс бара.
Для визуальной составляющей, можно упростить разметку, при этом воспользовавшись многослойным градиентом, параметры которого можно будет задавать и изменять из скриптов через CSS-переменную.
Установка значения вручную:
body { background-color: #5a5a5a; }
.progress {
height: 7px;
width: 100%;
border-radius: 4px;
background:
linear-gradient(to right, #ddd0 calc(var(--value, 0) * 1%), #ddd calc(var(--value, 0) * 1%)),
linear-gradient(to right, #235f67, #40a0b0);
}
<div class="progress" style="--value: 72"></div>
Динамическое изменение:
let progress = document.querySelector('.progress');
let input = document.querySelector('input[type="range"]');
input.addEventListener('input', (ev) =>
progress.style.setProperty('--value', ev.target.value)
);
body { background-color: #5a5a5a; display: flex; flex-flow: column nowrap; gap: 2em; }
.progress {
height: 7px;
width: 100%;
border-radius: 4px;
background:
linear-gradient(to right, #ddd0 calc(var(--value, 0) * 1%), #ddd calc(var(--value, 0) * 1%)),
linear-gradient(to right, #235f67, #40a0b0);
}
<div class="progress"></div>
<input type="range">
Подстановка значений из массива:
let progresses = document.querySelectorAll('.progress');
let values = [65, 32, 11, 16, 92];
progresses.forEach((el, index) => el.style.setProperty('--value', values[index]));
body { background-color: #5a5a5a; display: flex; flex-flow: column nowrap; gap: 2em; }
.progress {
height: 7px;
width: 100%;
border-radius: 4px;
background:
linear-gradient(to right, #ddd0 calc(var(--value, 0) * 1%), #ddd calc(var(--value, 0) * 1%)),
linear-gradient(to right, #235f67, #40a0b0);
}
<div class="progress"></div>
<div class="progress"></div>
<div class="progress"></div>
<div class="progress"></div>
<div class="progress"></div>
