I’m trying to show a loading indicator when executing a long-running task. The loader should remain visible for the entire duration of the task and then be hidden when the task completes. However, the loader–show class is briefly applied and does not stay visible at all during the execution of the task.
Here’s a simplified version of my code: https://jsfiddle.net/p6ejkdcb/
<button id="test">
Do Something
</button>
<div id="loader" class="loader">
Loading...
</div>
const button = document.getElementById("test");
const loader = document.getElementById("loader");
test.addEventListener("click", (_) => {
new Promise(function (resolve, reject) {
console.log("showLoader");
showLoader();
resolve();
})
.then(function (result) {
for (let i = 0; i < 500000; i++) {
console.log("do the work");
}
return result;
})
.then(function (result) {
console.log("hide the loader");
hideLoader();
return result;
})
})
function showLoader() {
loader.classList.add("loader--show");
}
function hideLoader() {
loader.classList.remove("loader--show");
}
.loader {
display: none;
&--show {
display: block;
}
}
Expected behaviour:
- The loader should become visible when I click the "Do Something" button.
- It should remain visible while the code inside the promise’s then() method executes.
- Once the task is complete, the loader should be hidden.
Actual behaviour:
- The loader briefly received the loader–show class but does not stay visible during the execution of the loop.
3
Answers
You should use a promise with
setTimeout
to mimic your heavy calculations.The
for
will complete instantlyWhen you add classlist with name
–loader–show
But in your css
You use class name as separate
Lile –loader{
&–show
}
Use like this
–loader–show{
Write css
}
You just need to hide your loader right after the
resolve()
call inside the Promise.