Reputation: 11
Until all events are completed changes in html do not occur
(function(){
function sleep(ms) {
const date = Date.now();
do {
} while (Date.now() - date < ms);
}
let button = document.getElementById('update');
//basic code example:
/*button.addEventListener('click', event => {
event.target.value = 'aaa';
sleep(1000);//or another long process
event.target.value = 'bbb';
});/**/
//even so:
button.addEventListener('click', event => {
event.target.value = 'aaa';
});
button.addEventListener('click', event => {
sleep(1000);//or another long process
});
button.addEventListener('click', event => {
event.target.value = 'bbb';
});
})();
<input type="button" value="Update" name="update" id="update">
This applies to all types of events.
What is the reason for this?
Is there a way to change html during(before) the execution of event?
Upvotes: 0
Views: 164
Reputation: 123026
Add the value change as callback to the long running function and use setTimeout
to trigger a repaint:
document.addEventListener("click", bttnEx);
function bttnEx(evt) {
const origin = evt.target;
if (origin.name === "update") {
origin.value = "waiting...";
const longRun = () => sleep(2000, () => origin.value = "done!");
return setTimeout(longRun, 1);
}
}
function sleep(ms, callback) {
const date = Date.now();
do {} while (Date.now() - date < ms);
callback();
}
<input type="button" value="Update" name="update" id="update">
You can also use requestAnimationFrame
in a nested fashion:
document.addEventListener("click", bttnEx);
function bttnEx(evt) {
const origin = evt.target;
if (origin.name === "update") {
const runSomethingLongAndReEnable = () => {
const date = Date.now();
do {} while (Date.now() - date < 2000);
origin.value = "Update";
origin.disabled = false;
};
const waitAndDisable = () => {
origin.value = "Busy...";
origin.disabled = true;
requestAnimationFrame(runSomethingLongAndReEnable);
};
return requestAnimationFrame(waitAndDisable);
}
}
body {
margin: 2rem;
}
input[disabled] {
color: red !important;
}
<input type="button" value="Update" name="update" id="update">
Upvotes: 0
Reputation: 12957
As Martin mentioned in the comments, you should read up on the Promise object, and asynchronous operations. see: Using Promises
Here is your snippet with the MDN example Promise.
(function () {
function sleep(ms) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('done');
}, ms);
})
}
let button = document.getElementById('update');
//basic code example:
button.addEventListener('click', event => {
sleep(2000).then(res => event.target.value = res);//or another long process
event.target.value = 'loading...';
});
})();
<input type="button" value="Update" name="update" id="update">
Upvotes: 1