here's a html p element. When clicked:
red than yellowrefresh-startThis is done in the click handler onClickRefresh.
However changes are reflected only after the timer is called, ends its operation and return. timer waits 5 sec (5000ms).
I would expect to see the changes immediately, before timer is called. that is:
this is not happening. How does it make sense?
function onClickRefresh(el){
//jquery selector
let id = "#" + el.id;
//read class
const co = (id)=>{ return $(id).attr("class")}
//current class
console.log("class before:", co(id));
//setting class - start rotating
el.className = "refresh-start";
console.log("class after:", co(id));
//temp color
$(id).css("background-color","red");
timer(5000);
$(id).css("background-color","yellow");
}
function timer(ms){
const d1 = new Date();
let cont = true;
while (cont){
let d2 = new Date();
cont = (d2-d1 >= ms ? false : true);
}
}
@keyframes rotate {
from {transform: rotate(0deg)}
to {transform: rotate(360deg)}
}
.refresh-start {
animation-name: rotate;
animation-duration: 1.5s;
animation-iteration-count: infinite;
animation-timing-function: linear;
animation-play-state: running;
}
.refresh-end{
animation-play-state: paused;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<p id="refreshNRList1" class="refresh-end" onclick="onClickRefresh(this)"/>
text
</p>
Your timer function is synchronous it blocks the next code until it is completely executed. try asynchronous timer
async function onClickRefresh(el) {
//jquery selector
let id = "#" + el.id;
//read class
const co = (id) => {
return $(id).attr("class");
};
//current class
console.log("class before:", co(id));
//setting class - start rotating
el.className = "refresh-start";
console.log("class after:", co(id));
//temp color
$(id).css("background-color", "red");
await timer(5000);
$(id).css("background-color", "yellow");
}
async function timer(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
@keyframes rotate {
from {transform: rotate(0deg)}
to {transform: rotate(360deg)}
}
.refresh-start {
animation-name: rotate;
animation-duration: 1.5s;
animation-iteration-count: infinite;
animation-timing-function: linear;
animation-play-state: running;
}
.refresh-end{
animation-play-state: paused;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<p id="refreshNRList1" class="refresh-end" onclick="onClickRefresh(this)"/>
text
</p>
Try using setTimeout
setTimeout(
() => {
$(id).css("background-color","yellow");
},
5000
);
This code calls a function after 5000 milliseconds, that changes the background-color to yellow. The rest of your code is executed immediately.
function onClickRefresh(el){
//jquery selector
let id = "#" + el.id;
//read class
const co = (id)=>{ return $(id).attr("class")}
//current class
console.log("class before:", co(id));
//setting class - start rotating
el.className = "refresh-start";
console.log("class after:", co(id));
//temp color
$(id).css("background-color","red");
setTimeout(
() => {
$(id).css("background-color","yellow");
},
5000
);
}
@keyframes rotate {
from {transform: rotate(0deg)}
to {transform: rotate(360deg)}
}
.refresh-start {
animation-name: rotate;
animation-duration: 1.5s;
animation-iteration-count: infinite;
animation-timing-function: linear;
animation-play-state: running;
}
.refresh-end{
animation-play-state: paused;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<p id="refreshNRList1" class="refresh-end" onclick="onClickRefresh(this)"/>
text
</p>
TL;DR: Use setTimeout():
//remove the "`timer(5000);`" line and the timer function.
setTimeout(() => {
$(id).css("background-color","yellow");
}, 5000)
Your problem is in the timer function. HTML/JavaScript/CSS are single-threaded. It means, that if you make something in an infinite loop, everything will stop. You had some kind of infinite loop in your timer function, though it ended at the end on 5 seconds, but in the meanwhile, everything was 'lagged' and the CSS animation couldn't start. For this reason you have to use this syntax:
setTimeout(() => {
//code...
}, 5000 /*delay in milliseconds*/)