Is there more efficient, proper way, to write a function like this? The effect I want to achieve is to remove CSS classes in three steps, one after another.
function loadColors(){
setTimeout(()=>{
document.querySelector('.class-1').classList.remove('class-x')
}, 0);
setTimeout(()=>{
document.querySelector('.class-2').classList.remove('class-z')
}, 100);
setTimeout(()=>{
document.querySelector('.class-3').classList.remove('class-y')
}, 200);
}
2 Answers 2
You can save the info in an array,then use Array.forEach() to execute.
const timeoutPieces = [
[".class-1", "class-x", 0],
[".class-2", "class-z", 100],
[".class-3", "class-y", 200],
];
timeoutPieces.forEach(p => {
setTimeout(() => {
document.querySelector(p[0]).classList.remove(p[1])
}, p[2]);
});
If you want to use es6,and have clear name for vairables,use Array Destructing
timeoutPieces.forEach(([selector, aClass, time]) => {
setTimeout(() => {
document.querySelector(selector).classList.remove(aClass)
}, time);
});
It's using array,is because the selector,class and timer you used are not likely to have relation,if you are certain the time for timeout is incremental by 100,you can use Array.map()
const addTimer = (piece, index) => [...piece, index * 100];
const timeoutPieces = [
[".class-1", "class-x"],
[".class-2", "class-z"],
[".class-3", "class-y"],
].map(addTimer);
timeoutPieces.forEach(([query, aClass, time]) => {
setTimeout(() => {
document.querySelector(query).classList.remove(aClass)
}, time);
});
async
await
and promise
One way to do this is to use promises and an async function.
async
functions stop execution each time they encounter an await
token and "await" the promise (if any) to resolve before continuing. async
functions are also promises themselves so you can await an async function as well.
Example
The example uses a timer event to resolve a promise. The function threeStep
uses the wait
function to pause execution for the set time.
To show how you can also chain the async function It repeats the 3 steps after the first lot are done by using the async function's returned promise
to start the second three steps.
const wait = time => new Promise(tick => setTimeout(tick, time));
async function threeStep(time) {
log(`Step A and wait ${time}ms`);
await wait(time);
log(`Step B and wait ${time}ms`);
await wait(time);
log(`Step C all done`);
}
threeStep(2000)
.then(() => {
log("Do it again");
threeStep(1000);
});
// a very hacky log function, don't try this at home. :P
function log(data) { logText.innerHTML += data + "<br>" }
<div id="logText"></div>
transition
property to control when your elements change visual state: developer.mozilla.org/en-US/docs/Web/CSS/transition developer.mozilla.org/en-US/docs/Web/CSS/CSS_Transitions/… \$\endgroup\$