Reputation: 791
I have this progress bar that gets created over a setTimeout of 2 seconds on click. Now I want to create and append to DOM a new progress bar on every click. How do I do that? I tried using a promise but that just gets resolved after setTimeout - not sure if it doing anything at all. Can I use request animation frame here?
(function() {
const container = document.getElementById('container');
const addBtn = document.getElementById('add');
const progress = document.getElementsByClassName('progress');
let promise = Promise.resolve();
document.addEventListener('click', function(e) {
// clone the progress made so far
const newProgress = Object.assign({}, progress);
// now add the new progress into container element, so its visible
container.appendChild(newProgress[0]);
promise = promise.then(() => new Promise((resolve) => {
setTimeout(() => {
newProgress[0].classList.add('active');
console.log(newProgress[0].classList)
setTimeout(() => {
resolve();
}, 2000);
}, 0);
}));
});
})();
#container {
margin: 20px;
}
.progress {
margin: 0 0 10px;
width: 500px;
height: 20px;
background-color: #e0e0e0;
}
.progress .bar {
width: 0;
height: 100%;
background-color: lightgreen;
transition: width 2s ease;
}
.progress.active .bar {
width: 100%;
}
<button id="add">Add</button>
<div id="container"></div>
<div style="display: none">
<div class="progress">
<div class="bar"></div>
</div>
</div>
Upvotes: 1
Views: 467
Reputation: 30360
The recommended method for duplicating DOM nodes (ie the node matching .progress
) is to use the .cloneNode()
method. In the case of your code, you'd also want to pass true
to .cloneNode()
to ensure that children of the progress node are also cloned.
So, if I understand your question correctly, then you want to clone the progress node and then delay assignment of the .active
class to the clone. This can be achieved by making the following revisions to your code:
(function(){
const container = document.getElementById('container');
const addBtn = document.getElementById('add');
// use querySelector to aquire progress node for subsequent cloning
const progress = document.querySelector('.progress');
addBtn.addEventListener('click', function(e) {
// use cloneNode to duplicate existing node on DOM rather than
// Object.assign as you currently are
const newProgress = progress.cloneNode(true);
container.appendChild(newProgress);
// delay assignment of '.active' class to clone
setTimeout(() => {
newProgress.classList.add('active');
}, 50);
});
})();
#container {
margin: 20px;
}
.progress {
margin: 0 0 10px;
width: 500px;
height: 20px;
background-color: #e0e0e0;
}
.progress .bar {
width: 0%;
height: 100%;
background-color: lightgreen;
transition: width 2s ease;
}
.progress.active .bar {
width: 100%;
}
<button id="add">Add</button>
<div id="container"></div>
<div style="display: none">
<div class="progress">
<div class="bar"></div>
</div>
</div>
Upvotes: 1