SetTimeOut в цикле для массива
подскажите, пожалуйста, почему не работает код. Пользователь вводит в input строку с числами через запятую, например "2,5,7", строка преобразуется в массив чисел. Полоса прогресс-бара до полной загрузки должна сдвинуться ровно столько раз, сколько чисел в массиве ("2,5,7" - этом примере 3 раза). При этом задерживаться на указанное число секунд, т.е. сначала на 2, потом на 5 и на 7(числа будут зависеть от того, что ввел пользователь). Функция moveProgressBar вроде как срабатывает правильно. Значит главная проблема заключается в setTimeout:
let width = 0;
btn.addEventListener ("click", function getInterval() {
let delaysArr = input.value.split(",");
for (let delay of delaysArr){
let id = setTimeout(moveProgressBar, delay*1000);
function moveProgressBar() {
if (width >= 100) {
clearTimeout(id);
} else {
width += 100/delaysArr.length;
greenProgressBar.style.width = width + '%'
counter.innerHTML = width.toFixed(2) * 1 + '%';
}}}})
Пробовала читать проблемы у других на эту тему, но так не поняла, что конкретно нужно исправить у меня в коде. По другому примеру сделала второй вариант кода, но он тоже не работает:
let width = 0;
let delaysArr = [];
function getInterval(array, delegate, delay) {
array.forEach(function (el) {
setTimeout(()=>{delegate();}, el * delay);
})
}
btn.addEventListener ("click", ()=>{
delaysArr = input.value.split(",");
getInterval(delaysArr,
function () {
width += 100/delaysArr.length;
greenProgressBar.style.width = width + '%'
counter.innerHTML = width.toFixed(2) * 1 + '%';
}, 1000)})
Вот ссылка на полный код: https://codepen.io/Kalskaya/pen/PoQPqEz; Знаю, что главная проблема, что setTimeOut находится в цикле, не знаю, что именно исправить. Скорее всего вопрос глупый, но уже целый день не могу найти правильное решение, поэтому прошу помощи
Ответы (1 шт):
Если я правильно понял, то основная проблема была в том, что страница перезагружалась, а так я сделал небольшой рефакторинг, логику почти не менял:
const greenProgressBar = document.getElementById('greenProgressBar');
const counter = document.getElementById('counter');
const btn = document.getElementById('start');
const input = document.getElementById('delays');
const form = document.getElementById('form');
form.addEventListener('submit', (e) => e.preventDefault()); //Чтобы страница не перезагружалась
let width = 0;
const moveProgressBar = (parts) => {
width += 100 / parts;
if (width > 100) width = 100;
greenProgressBar.style.width = width + "%";
counter.innerHTML = width.toFixed(2) + "%";
}
btn.addEventListener('click', () => {
const delaysArr = input.value.split(',').map(x => Number(x.trim()));
for (const delay of delaysArr) {
setTimeout(() => {moveProgressBar(delaysArr.length)}, delay * 1000);
}
});
#greyProgressBar {
display: flex;
width: 100%;
height: 30px;
background-color: grey;
margin-top: 10px;
position: relative;
}
#greenProgressBar {
display: flex;
width: 0%;
height: 30px;
background-color: #4caf50;
}
#counter {
display: flex;
justify-content: center;
align-items: center;
color: white;
position: absolute;
top: 0px;
bottom: 0px;
left: 0px;
right: 0px;
}
<form id="form">
<label for="delays" style="color:red">Set delays list:</label>
<input id="delays" type="text">
<button id="start">Start</button>
</form>
<div id="greyProgressBar">
<p id="counter">0%</p>
<div id="greenProgressBar"></div>
</div>