Reputation: 1644
I've looked around for a soundproof solution to my problem but was not able to find many SO questions like this.
My move
function gets called each click on a tile, I want to block the user from moving whilst they are currently in motion to block overlapping execution bugs.
The functions work as following:
move: function(steps){
for (var stepx in steps) {
window.setTimeout(. . ., 300 * stepx);
}
}
Which iterates, adding a forward 300ms to when the function is going to be called each time. If it's 5 steps, it'll finish after 1.5 seconds.
But, when the user clicks twice it sets up a parallel bunch of handlers that glitch the user from two areas: the original path being travelled and the secondary.
Is there a way to block execution or queue the timeouts?
Upvotes: 0
Views: 472
Reputation: 33972
You just need to save the timeout to a variable and call clearTimeout()
- however, your example creates multiple timeouts in a loop, so you'd need to save them all and then stop them all. It could be done like this:
var timers = [];
var running = false;
function makeSteps(steps) {
if (!running) {
running = true;
for (var i = 0; i <= steps; i++) {
timers.push(setTimeout(function() {
console.log("Step");
}, 300 * i));
}
}
}
function stopAllSteps() {
for (var i = 0; i <= timers.length; i++) {
clearTimeout(timers[i]);
}
running = false;
console.log("stopped!");
}
<button type="button" onclick="makeSteps(100)">Start</button>
<button type="button" onclick="stopAllSteps()">Stop</button>
Upvotes: 1
Reputation: 23495
You could use of a variable to block the user clicks until it gets done.
If I understood well what you asked for.
let inProgress = false;
function clickFunc(steps) {
console.log('The user clicked');
if (inProgress) {
console.log('Action already in progress');
return;
}
inProgress = true;
for (let i = 0; i < steps; i += 1) {
window.setTimeout(() => {
// if the last step is over, we stop the click block
if (i === steps - 1) {
inProgress = false;
}
console.log('One step done');
}, 300 * i);
}
}
.button {
height: 2em;
width: 10em;
background-color: #444444;
color: white;
cursor: pointer;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
}
.button:hover {
opacity: 0.9;
}
<div class="button" onclick="clickFunc(3)">Button</div>
Upvotes: 0