规则:
>每次点击都会添加< progress>元件.
>每个进度条将设置为动画.
>动画要等到之前的动画完成后才能开始.
问题:
如果快速单击,它将仅对最后一个进度条进行动画处理.动画应该一个接一个地发生直到完成.
题:
快速单击时,为什么动画混乱?
HTML:
<div class="container">
<div class="add-progress-container">
<input class="input-seconds" type="number" min="1" max="10" value="1">
<button class="add-progress">Add progress</button>
</div>
<div class="progress-container"></div>
</div>
JS:
const container = document.querySelector('.progress-container');
const inputSeconds = document.querySelector('.input-seconds');
const addBtn = document.querySelector('.add-progress');
let animating = false;
function animateProgress(duration,el) {
const intervalId = setInterval(() => {
if(el.value >= el.max) {
animating = false;
window.clearInterval(intervalId);
console.log('finished');
checkQueue();
return;
}
el.value += el.max/duration;
},1000);
}
function getSeconds() {
return parseInt(inputSeconds.value,10);
}
let progressCount = 0;
function createProgress() {
const template = `<progress data-progress="${progressCount}" value="0" max="100"></progress>`;
container.innerHTML += template;
const el = document.querySelector(`[data-progress="${progressCount}"]`);
progressCount++;
return el;
}
let queue = [];
function addProgress() {
const el = createProgress()
queue.push(el);
checkQueue();
}
function checkQueue() {
if(queue.length && !animating) {
animating = true;
animateProgress(getSeconds(),queue.shift());
}
}
addBtn.addEventListener('click',addProgress);
最佳答案
innerHTML =分配将重新创建container元素内的所有先前元素,这意味着您对其他进度元素的引用不再是此分配创建的实际元素.
您应该添加一个新的progress元素,如下所示:
function createProgress() {
const el = document.createElement("progress");
el.setAttribute("data-progress",progressCount);
el.setAttribute("value",0);
el.setAttribute("max",100);
container.appendChild(el);
return el;
}
正如Makyuu在下面评论的那样,仅在其动画开始时才对单个进度元素采取步骤数.这意味着,如果您更改输入值,则它也将应用于先前创建的元素(当它们尚未开始设置动画时).
queue.push([getSeconds(),el]);
和:
animateProgress(...queue.shift());