Adding a timed delay after pressing a button to prevent button spam - javascript

Say I have 4 buttons
<button id="one">One</button>
<button id="two">Two</button>
<button id="three">Three</button>
<button id="four">Four</button>
and to prevent spam, I want to make it so that whenever any of the buttons are pressed, none of them are able to be pressed again for the next 0.6 seconds.
How might I achieve this?

You can use this javascript code:
var btns = document.getElementsByTagName('button');
for(var i=0;i<btns.length;i++){
btns[i].addEventListener('click', function(){
disableButtons(true);
setTimeout(function(){disableButtons(false);}, 600);
});
}
function disableButtons(state){
for(var i=0;i<btns.length;i++){
btns[i].disabled = !!state;
}
}
Of course, you need to run this code after your page is loaded.

One way to do this is with a "click shield".
Here's how you can do it with jQuery.
var clickShield = false;
$('button').on('click', function() {
if (!clickShield) {
clickShield = true;
console.log('handle click event');
setTimeout(function() {
clickShield = false;
}, 600);
}
});

With jQuery you can do something like:
<button id="one">One</button>
<button id="two">Two</button>
<button id="three">Three</button>
<button id="four">Four</button>
$("button").on("click", function(e) {
$("button").attr('disabled', 'disabled');
setTimeout(function() {
$("button").removeAttr('disabled');
}, 600);
});

// Get button elements
var els = document.getElementByTagName('button');
// Add an event handler to click event
// that triggers settimeout to set the disable value
els.addListener('click', function(){
setTimeout(els.disable, 600);
}, true);
not tested

Like prasadmadanayake says in his comment you can do it by disable/enable the button.
Here is a working example:
var intVal = 0;
$('button').on('click',function (e) {
var id = $(this).attr('id');
$('#'+id).attr('disabled', 'disabled');
setTimeout(function(){enable(id)}, 3000);
return true;
});
function enable (id) {
$('#'+id).removeAttr('disabled');
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<button id="one">One</button>
<button id="two">Two</button>
<button id="three">Three</button>
<button id="four">Four</button>

Related

Callback Function does not work with for Loop

Why doesn't the callButtonTwo() function work on all buttons? Only button1 reacts to it?
document.querySelector("h1").addEventListener("click", function() {
alert("Working!");
})
var totalButton = document.querySelectorAll(".testSecond").length;
for (var i = 0; i < totalButton; i++) {
document.querySelectorAll(".testSecond")[i].addEventListener("click", function() {
var buttonNow = this.innerHTML;
callButtonOne(buttonNow);
callButtonTwo(buttonNow);
});
}
function callButtonOne() {
alert("I got clicked!");
};
function callButtonTwo() {
var changeRed = document.querySelector(".testSecond");
changeRed.classList.add("red");
setTimeout(function() {
changeRed.classList.remove("red");
}, 300);
};
.red {
background-color: red;
}
<h1 class="testFirst">Hello World!</h1>
<button class="testSecond button1" type="button" name="button">button1</button>
<button class="testSecond button2" type="button" name="button">button2</button>
<button class="testSecond button3" type="button" name="button">button3</button>
<button class="testSecond button4" type="button" name="button">button4</button>
<button class="testSecond button5" type="button" name="button">button5</button>
While, inside your click handler you have var buttonNow = this.innerHTML; which operates on that button, when you call callButtonTwo you say var changeRed = document.querySelector(".testSecond"); which operates on the first button (no matter which button you click).
You need to tell it which button you are dealing with (e.g. by passing this as an argument)
The problem is, that your querySelector in callButtonTwo just finds the first button because all of them have the same class .testSecond.
One possible solution is to add the reference of the button which should be colored red to the callButtonTwo function and use the reference to add the class name.
It would look like this:
function callButtonTwo(button) {
button.classList.add("red");
setTimeout(function() {
button.classList.remove("red");
}, 300);
};
And you would call it like this: callButtonTwo(this);
Here's a working example based on the code you provided.
Inside callButtonTwo you're querying .testSecond again which will always return the first element in the page with that class. If you want to handle each button differently you should pass the button element as a parameter to callButtonTwo, like so:
var totalButton = document.querySelectorAll(".testSecond").length;
for (var i = 0; i < totalButton; i++) {
document.querySelectorAll(".testSecond")[i].addEventListener("click", function() {
var buttonNow = this.innerHTML;
callButtonOne(buttonNow);
callButtonTwo(this); // 'this' in this case is the clicked button element
});
}
[...]
function callButtonTwo(button) {
button.classList.add("red");
setTimeout(function() {
button.classList.remove("red");
}, 300);
};
I would also consider to change the way you're iterating your elements in order to query the DOM less frequently:
// 'querySelectorAll' returns an array which can be directly iterated using its method 'forEach'
document.querySelectorAll(".testSecond").forEach(function(button) {
button.addEventListener("click", function() {
var buttonNow = this.innerHTML;
callButtonOne(buttonNow);
callButtonTwo(this);
});
});

Is there a way I could assign 2 separate functions on 2 onclick in a button?

I wanted to:
play the animation on my first click and
stop it on my second click of the same button.
Thanks.
Here is the simplest solution using closures, you should learn more on how closures work.
function generateMyStatefullFunction(){
var someState = false;
return function theActualFunctionThatDoesThings(){
if (someState){
console.log("State will be set to false, next click wont trigger this message");
}
someState = !someState;
}
}
var onClickHandler = generateMyStatefullFunction();
document.getElementById("button").addEventListener('click', onClickHandler);
<button id="button"> Fire every second click</button>
You can do like this
function performAction(event){
var button = event.currentTarget;
var action = button.innerHTML;
if(action == "Play"){
button.innerHTML = "Stop"
//play animation
} else {
button.innerHTML = "Play"
//stop animation
}
}
<div>
<button onclick="performAction(event)" >Play</button>
</div>

Clipboard.js loop buttons

I use clipboard.js and after a click on one of my buttons I want to show a success message under the button, but I am not able to loop throught.
This is the button:
<button type="button" class="clipboard-button button-rect" data-clipboard-text="{{ site.author.email|safe_email }}">
<span class="button-text">Get in touch</span>
<span class="clipboard-message">My E-Mail has been copied</span>
</button>
And this the js:
var clipboard = new ClipboardJS('.clipboard-button');
clipboard.on('success', function () {
var message = document.querySelectorAll('.clipboard-message');
message.style.opacity = '1';
setTimeout(function () {
message.style.opacity = '0';
}, 2000);
});
I want to show the message under the button which was pressed and not for every button.
I would appreciate your help, I tried so much. I'm an JS beginner btw, so be patient please. :)
On thing you should look at is achieving to retrieve the clicked DOM element (a button in this case). It will then be easy to find the corresponding .clipboard-message span element.
To retrieve the clicked element you can use the parameter given to the success event callback function, like stated here: https://clipboardjs.com/#events
Then your JavaScript code becomes:
var clipboard = new ClipboardJS('.clipboard-button');
clipboard.on('success', function (e) {
// e.trigger corresponds to the clipboard-button DOM element that triggered the event
// You can then use querySelector(...) to retrieve to first child element with the class clipboard-message
var message = e.trigger.querySelector('.clipboard-message');
message.style.opacity = '1';
setTimeout(function () {
message.style.opacity = '0';
}, 2000);
});
Here is a working code snippet for you to try:
var clipboard = new ClipboardJS('.clipboard-button');
clipboard.on('success', function (e) {
var message = e.trigger.querySelector('.clipboard-message');
message.style.opacity = '1';
setTimeout(function () {
message.style.opacity = '0';
}, 2000);
});
.clipboard-message {
color: green;
opacity: 0;
}
<script src="https://cdn.jsdelivr.net/npm/clipboard#2/dist/clipboard.min.js"></script>
<button type="button" class="clipboard-button button-rect" data-clipboard-text="{{ site.author.email|safe_email }}">
<span class="button-text">Get in touch</span>
<span class="clipboard-message">My E-Mail has been copied</span>
</button>
<button type="button" class="clipboard-button button-rect" data-clipboard-text="{{ site.author.email|safe_email }}">
<span class="button-text">Here is your ID</span>
<span class="clipboard-message">My ID has been copied</span>
</button>

On click & hold for a duration alert something

$('#action').click(function() {
if(setTimeout(function() {}, 1000)) {
alert("Hold");
} else {
alert("Click");
}
})
<!-- begin snippet: js hide: false console: true babel: false -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id='action'>Hello</button>
I'm trying to alert Click if i just clicked on the button, And alert Hold if i hold clicking the button for 2s,
The problem is that it always alerts Hold after clicking.
How to fix that And how to count the time of holding the button exactly?
Try the snippet below:
$(document).ready(function() {
var timeoutId = 0;
var functionCalled = false;
$("#btn").on("mousedown", function() {
timeoutId = setTimeout(btnHeld, 2000);
}).bind("mouseup", function(e) {
if (!functionCalled) {
alert('clicked');
}
functionCalled = false;
clearTimeout(timeoutId);
});
function btnHeld() {
functionCalled = true;
alert("hold");
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="btn">click</button>
You need to handle the mousedown event, set a timer for two seconds, then cancel that timer in the mouseup event.

Reenable button onClick

I tried to disable my button with an onClick function using this:
document.getElementById("btn").onClick = null;
How can I reenable it back again?
example:
if(some condition)
document.getElementById("btn").onClick = null;
else
//reenable it again
Try like this
disable
document.getElementById("btn").disabled=true;
enable
document.getElementById("btn").disabled=false;
Simple way is that save old onclick's method to value (tempFn). Then you can reenable again.
var tempFn;
document.getElementById("btn2").onclick = function () {
if (!tempFn) {//some condition
tempFn = document.getElementById("btn").onclick;
document.getElementById("btn").onclick = null;
} else {
document.getElementById("btn").onclick = tempFn;
tempFn = null;
}
}
document.getElementById("btn").onclick = function () {
alert("btn");
}
<button id="btn">btn</div>
<button id="btn2">Disable/Enable</div>
You can do it with jquery
$(function(){
if(smth){
//Set button disabled
$("#btn").attr("disabled", "disabled");
}else{
$("#btn").removeAttr("disabled");
}

Categories

Resources