javascript - 动画元素队列正在跳到最终元素
问题描述
代码笔
规则:
- 每次点击都会添加一个
<progress>
元素。 - 每个进度条都将充满动画。
- 动画在前一个完成之前不会开始。
问题:
如果您快速单击,它只会为最后一个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+=
分配将重新创建容器元素中的所有先前元素,这意味着您对其他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());
推荐阅读
- sqlite - 无法将数据写入 Flask 中的数据库
- mvvm - Xamarin Forms MVVM UWP ListView 绑定不起作用
- php - 如何在php中根据数组拆分字符串
- node.js - Node js peerwire 协议实现
- python - ecoinvent 3.5 导入错误:MaybeEncodingError:
- angular - Angular 7 Material `panelClass` 属性应该如何使用?
- python - 非 UTC 日期时间对象的时间戳两次减去小时
- excel - VBA:将数据复制到现有的列表对象中
- xaml - 如何使用 ItemsSource 中每个项目的索引对 Xamarin.Forms ListView 中的项目进行编号,包括何时删除项目?
- google-kubernetes-engine - GKE Beta 日志记录体验 - JSON 解析丢失