Reputation: 155
I want to prevent my click handler from executing multiple times, however it is not working as expected. Is my approach in the right direction? I want this handler to get executed when user clicks on button just once. This handler can get executed again of course (after the execution has completed).
var init = false,
i = 1;
$('button').on('click', function() {
if (init) {
return;
}
init = true;
(function() {
// this for loop is for example purposes, just to have something running
for (var i = 0; i < 5000; i++) {
$('.text').append(i)
}
init = false;
}());
$('.counter').html(i);
i++
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="button">Button</button>
<div class="text"></div>
<div class="counter"></div>
Upvotes: 1
Views: 117
Reputation: 155
After figuring out that the UI was being blocked, I looked into solutions to 'chunking' the loop into smaller loops, allowing the UI to become unblocked and other functions to be executed.
Chunked for loop
function loop(arr, fn, before, callback) {
let index = 0,
step = 50,
stepTotal = step;
before();
(function chunk() {
while(index < arr.length && index < stepTotal) {
fn(arr[index], index);
index++;
}
if (index < arr.length) {
stepTotal+=step;
setTimeout(chunk, 0);
} else {
callback();
}
})()
}
Upvotes: 0
Reputation: 1
Try setting button
property disabled
to true
at beginning of init
, using .hide()
, .delay()
, .show()
, setting disabled
property to false
var count = 1,
max = 5000,
init = function() {
$(this).prop("disabled", true)
.off("click.count");
$(".counter").html(count);
count++;
$(this).hide(0, function() {
for (var i = 0; i < max; i++) {
$(".text").append(i);
}
}).delay(max / 2).show(function() {
$(this).prop("disabled", false)
.on("click.count", init)
})
};
$("button").on("click.count", init);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
<button id="button">Button</button>
<div class="text"></div>
<div class="counter"></div>
Upvotes: 1
Reputation: 9060
Here try this solution.
At first we register click handler to button :
$('button').on('click', runThis );
And here the runThis() handler function :
function runThis() {
// register off click handler on button
$('button').off('click');
// loop over i
for (var i = 0; i < 2000; i++) {
$('.text').append('<br/>' + i);
}
// if execution finish
if (i == 2000) {
// register back handler
addBack();
}
}
And here we on back the click handler on button :
function addBack() {
$('button').on('click', runThis );
}
Upvotes: 1