I have a simple code like in below snippet to have alert whenever a button is clicked and alert is shown, that runs alright but with certain drawbacks (know that this is how setTimeout
works).
Here when you click button 2,3,4 times , than alert is shown that many times only. But I want alert only 1 time which is called from 1st click and ignore further clicks until 3 second are complete for 1st click.
function alertBtn() {
setTimeout(alertFunc, 3000);
}
function alertFunc() {
alert("Alert is clicked so remain alerted");
}
<button onclick="alertBtn()">Alert me</button>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
Is it possible with pure JavaScript way? It's may be similar to method that SO uses like we can't comment again within 5s(or something), the button is kinda disabled for that time interval. Kind of barrier for 5sec
CodePudding user response:
You may use clearTimeout()
for that which cancels a timeout previously established by calling setTimeout()
let time;
let clicked = false;
function alertBtn() {
if (!clicked){
clicked = true;
clearTimeout(time);
time = setTimeout(alertFunc, 3000);
}
}
function alertFunc() {
alert("Alert is clicked so remain alerted");
clicked = false;
}
<button onclick="alertBtn()">Alert me</button>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
clearTimeout
- https://developer.mozilla.org/en-US/docs/Web/API/clearTimeout
Debouncing and throttling in JavaScript
CodePudding user response:
It sounds like you're looking to do something called throttling. Here's an example of how to implement it:
const throttle = function (fn, delay) {
let timeout;
return function (...args) {
if (!timeout) {
const returnVal = fn.apply(this, args);
timeout = setTimeout(() => {
timeout = undefined;
}, delay);
return returnVal;
}
};
};
That throttle
function allows you to transform a normal function into a throttled function, which will only be executed the first time it is called in a given delay
time (specified in milliseconds to match the behaviour of setTimeout
).
It works by creating a new function that sets a timeout the first time it is called, and calls the initial function. Then, if the throttled function is called again before the timeout is finished, it won't call the initial function again.
If you want to throttle your function by 3 seconds, then you should pass the value 3000
as the delay
argument so the timeout created lasts for 3 seconds. You can crete only a throttled function by passing an anonymous function to throttle
, like this:
const throttle = function (fn, delay) {
let timeout;
return function (...args) {
if (!timeout) {
const returnVal = fn.apply(this, args);
timeout = setTimeout(() => {
timeout = undefined;
}, delay);
return returnVal;
}
};
};
const alertBtn = throttle(function () {
alert("Alert is clicked so remain alerted");
}, 3000);
<button onclick="alertBtn()">Alert me</button>
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
Maybe something like this:
let clickedOnce = false;
function alertBtn() {
if (!clickedOnce) {
clickedOnce = true;
setTimeout(alertFunc, 3000);
}
}
function alertFunc() {
alert("Alert is clicked so remain alerted");
clickedOnce = false;
}
<button onclick="alertBtn()">Alert me</button>
<iframe name="sif4" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
The easiest approach was to simply control the buttons disabled
state via setTimeout
. A handler does take care of exeuting the alertFunc
and of disabling the button on click and initiate the time shifted active state of the latter ...
function alertFunc() {
alert("Alert is clicked so remain alerted");
}
function controlButtonAbility(btn) {
btn.disabled = true;
setTimeout(() => btn.disabled = false, 5000);
}
function handleButtonClick(evt) {
const btn = evt.currentTarget;
controlButtonAbility(btn);
alertFunc();
}
document
.querySelector('button')
.addEventListener('click', handleButtonClick);
<button>Alert me</button>
<iframe name="sif5" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
Edit
"Nice solution, thanks for response( 1). But can the alert too be executed after 3s time"
sure ...
function alertFunc() {
alert("Alert is clicked so remain alerted");
}
function controlButtonAbility(btn) {
btn.disabled = true;
setTimeout(() => btn.disabled = false, 5000);
}
function handleButtonClick(evt) {
const btn = evt.currentTarget;
controlButtonAbility(btn);
// alertFunc();
setTimeout(alertFunc, 2000);
}
document
.querySelector('button')
.addEventListener('click', handleButtonClick);
<button>Alert me</button>
<iframe name="sif6" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>