Set a delay between each click in loop - javascript

I would like to simply set a delay between each click.
Shown below is the script I created. It works fine with clicking each element the way I want it to. The problem is that it clicks each element almost at the same time causing me horrible lag.
Original Code.
var timerVar = setInterval (function() {DoMeEverySecond (); }, 5000); //
<< set to 2 seconds.
function DoMeEverySecond ()
{
(function() {
document.getElementsByName("zTab")[0].click();
document.getElementsByName("zButton")[0].click();
document.getElementsByName("zClose")[0].click();
})();
}
Would it be possible to do something like this.
var timerVar = setInterval (function() {DoMeEverySecond (); }, 5000); //
<< set to 2 seconds.
function DoMeEverySecond ()
{
(function() {
document.getElementsByName("zTab")[0].click();
-----------A DELAY HERE!-----------
document.getElementsByName("zButton")[0].click();
---------- ANOTHER ONE HERE! ----------------
document.getElementsByName("zClose")[0].click();
})();
}
The code is very simple, I tried to explain it as best as I could. Could someone help me out on this piece of code

Here's a live demo of a potential solution. See the inline comments:
// Lets just add some logging here for when the buttons are clicked
document.querySelectorAll('.z-tab').forEach(element => {
element.addEventListener('click', e => console.log('Z Tab'));
});
document.querySelectorAll('.z-button').forEach(element => {
element.addEventListener('click', e => console.log('Z Button'));
});
document.querySelectorAll('.z-close').forEach(element => {
element.addEventListener('click', e => console.log('Z Close'));
});
// Let's take advantage of async/await
async function DoMeEverySecond () {
const elementClassNames = ['.z-tab', '.z-button', '.z-close'];
for (let i = 0; i < elementClassNames.length; i++) {
const element = document.querySelectorAll(elementClassNames[i])[0];
await delayFor(1000); // Let's wait 1000ms between each click
element.click()
}
}
// Delay function that will resolve a promise after the setTimeout delay has been passed.
function delayFor(delay) {
return new Promise((resolve) => {
setTimeout(() => {
resolve();
}, delay);
});
}
DoMeEverySecond ();
<h2>Z Tabs</h2>
<button class="z-tab">1</button> <button class="z-tab">2</button>
<h2>Z Buttons</h2>
<button class="z-button">1</button> <button class="z-button">2</button>
<h2>Z Close</h2>
<button class="z-close">1</button> <button class="z-close">2</button>

Shure you can add delays, but as #Brock Adams mentioned, better use a different approach, like a promise-chain, to be shure all clicks were triggered, before looping again.
I assume a delay of 1 second, you can change this, but be aware, that if you add a delay in total of more that 5 seconds, the click-actins will overlap per interval.
So your code with delays:
function doMeInInterval () {
document.querySelector("[name=zTab]").click();
setTimeout(function() {
document.querySelector("[name=zButton]").click();
setTimeout(function() {
document.querySelector("[name=zClose]").click();
}, 1000);
}, 1000);
}
var timerVar = setInterval(doMeInInterval, 5000);

Related

clearTimeout on mouseup doesnt work right

I want to click on a point and delete it, but when i press my mouse button down for 3 seconds, i want to do something else with this point. My problem is, that the code doesnt clear the timer, it just deletes the point after 3 seconds, no matter how long i clicked it on the point.
Im working with setTimeout and clearTimeout.
function click(event,d){
timer= setTimeout(function(){
/* do something */
},3000)
}
function clickRelease(timer){
clearTimeout(timer)
}
divMag1=d3.selectAll(".scatterlayer .trace .points path ")
divMag1.on("mousedown", click)
divMag1.on("mouseup",clickRelease)```
V3 - I think you're deleting the target before you can execute what you want.
Note that setTimout may take more than 3 seconds to execute.
Try:
function click(event) {
const currentTarget = event.currentTarget; // for some reason event.target is null in the timer handler, this fixes it 🤷
const timer = setTimeout(() => {
currentTarget.removeEventListener('mouseup', deleteTarget);
console.log('stuff');
// do stuff
}, 3000);
function deleteTarget() {
clearTimeout(timer);
console.log('deleted');
currentTarget.removeEventListener('mouseup', deleteTarget); // not required if you're actually deleting the target
// remove target
}
currentTarget.addEventListener('mouseup', deleteTarget);
}
document.querySelector('#but').addEventListener('mousedown', click)
<button id="but">Click</button>
V1:
let timer;
function click(event,d){
timer= setTimeout(function(){
/* do something */
},3000);
}
function clickRelease(){
clearTimeout(timer)
}
divMag1=d3.selectAll(".scatterlayer .trace .points path ")
divMag1.on("mousedown", click)
divMag1.on("mouseup",clickRelease)
You should first declare timer variable. Then to make your mouseup event works on you should wrap clickRelease to event funtion again or use it simply:
...
.addEventListener("mouseup", function() { clearTimeout(timer) })
Working example with button:
var timer
function click(event, d) {
timer = setTimeout(function () {
console.log('do something')
}, 1000)
}
function clickRelease(timer){
clearTimeout(timer)
}
var divMag1 = document.querySelector('#but')
divMag1.addEventListener("mousedown", click)
document.addEventListener("mouseup", function() { clickRelease(timer) })
<button id="but">Click</button>
If you want event to doing something repeatedly while button is down you need to use setInterval not setTimeout like this:
var timer
function click(event, d) {
timer = setInterval(function () {
console.log('do something')
}, 1000)
}
var divMag1 = document.querySelector('#but')
divMag1.addEventListener("mousedown", click)
document.addEventListener("mouseup", function() { clearInterval(timer) })
Note for clearing interval uses clearInterval not clearTimeout. Also the mouseup event handler attached on whole document in my solution not on button.

Stopping a jQuery function after modal closes

I have a function that is repeated every 3 seconds like this:
function myFunction() {
// Do something sexy
var delay = 3000;
setTimeout(function() {
myFunction();
}, delay);
}
It's running inside a Bootstrap modal window and it should only run when that window is open.
I tried wrapping the delay into a something like:
if ($('#modal-task').hasClass('in')){
var delay = 3000;
setTimeout(function() {
myFunction();
}, delay);
}
But the problem is then if the modal is closed and re-opened, the function runs twice and more times each time it's closed and opened.
How do I kill the function completely when the modal is closed/invisible?
this might work, instead of if statement
function something_sexy () {
// Do something sexy
var delay = 3000;
setTimeout(function() {
myFunction();
}, delay);
}
while ($('#modal-task').hasClass('in')) {
something_sexy();
}
When you close the Bootstrap model 'in' will remove from model class. So when close the model clear the timeout It will work.
like.
function myFunction() {
// Do something sexy
console.log("test");
var delay = 3000;
//Assign setTimeout in variable timerval
let timerval = setTimeout(function() {
myFunction();
}, delay);
//when close the model clear the timeout
if (!$('.#modal-task').hasClass("in")){
clearTimeout(timerval );
}
}

How can I write a function that undoes the action after a few seconds?

How can I write a function that undoes the action after a few seconds?
I am adding a class to an element with the purpose to create a short animation. I know I can set the animation time with css, but how do I remove the class after a few seconds?
Should I create another animation setTimeout()?
Here is my code:
const copyAnimation = (item) => {
item.classList.add('copied');
};
copyTextArea.addEventListener('click', () => {
copyAnimation(clonedCode);
});
like this?
const copyAnimation = (item) => {
item.classList.add('copied');
setTimeout(function(){ item.classList.remove('copied'); }, 3000);
};
copyTextArea.addEventListener('click', () => {
copyAnimation(clonedCode);
});
We can go with this =>
setTimeout(
function()
{
$(this).removeClass("loader-input");
}, 3000
);

Clear timeout that's active

I have a jQuery ajax where I use setTimeout(). Sometimes, the user triggers the ajax multiple times, before the setTimeout() has kicked off.
So is it possible to clear an active version of the setTimeout() that was triggered previously by adding clearTimeout() like this:
clearTimeout(time);
var time = setTimeout(function() {
$('#hello').fadeOut();
},2600);
Or maybe I need to add some form of global variable?
Depending on what you're doing you may want to act on the first click and ignore subsequent clicks until the first one is finished, or you way want to reset the timer and only act 2.6 seconds after the last click... I gave examples of both, let me know if anything needs clarification..
(function() {
let time, btn = document.getElementById('btn1');
btn.onclick = function() {
if (time) clearTimeout(time);
time = setTimeout(function() {
alert("what the stink?!");
}, 2600);
}
})();
(function() {
let time, btn = document.getElementById('btn2');
btn.onclick = function() {
if (time) return;
time = setTimeout(function() {
alert("what the butts?!");
time = null;
}, 2600);
};
})();
<button id=btn1>Only reacts to last press</button>
<button id=btn2>Only reacts to first press</button>
Here's a quick example which answers your question and illustrates the wonder of closure.
document.getElementById('inputBox').addEventListener('keyup', Delay());
function MyFunction(){
console.log(this.value);
}
function Delay(){
var timer = 0;
return function(){
clearTimeout(timer);
timer = setTimeout(MyFunction.bind(this), 1000);
}
}
https://jsfiddle.net/tlynch001/7y3vnfjn/

setTimeout / clearTimeout problems

I try to make a page to go to the startpage after eg. 10sec of inactivity (user not clicking anywhere). I use jQuery for the rest but the set/clear in my test function are pure javascript.
In my frustation I ended up with something like this function that I hoped I could call on any click on the page. The timer starts fine, but is not reset on a click. If the function is called 5 times within the first 10 seconds, then 5 alerts will apear... no clearTimeout...
function endAndStartTimer() {
window.clearTimeout(timer);
var timer;
//var millisecBeforeRedirect = 10000;
timer = window.setTimeout(function(){alert('Hello!');},10000);
}
Any one got some lines of code that will do the trick?
- on any click stop, reset and start the timer.
- When timer hits eg. 10sec do something.
You need to declare timer outside the function. Otherwise, you get a brand new variable on each function invocation.
var timer;
function endAndStartTimer() {
window.clearTimeout(timer);
//var millisecBeforeRedirect = 10000;
timer = window.setTimeout(function(){alert('Hello!');},10000);
}
The problem is that the timer variable is local, and its value is lost after each function call.
You need to persist it, you can put it outside the function, or if you don't want to expose the variable as global, you can store it in a closure, e.g.:
var endAndStartTimer = (function () {
var timer; // variable persisted here
return function () {
window.clearTimeout(timer);
//var millisecBeforeRedirect = 10000;
timer = window.setTimeout(function(){alert('Hello!');},10000);
};
})();
That's because timer is a local variable to your function.
Try creating it outside of the function.
A way to use this in react:
class Timeout extends Component {
constructor(props){
super(props)
this.state = {
timeout: null
}
}
userTimeout(){
const { timeout } = this.state;
clearTimeout(timeout);
this.setState({
timeout: setTimeout(() => {this.callAPI()}, 250)
})
}
}
Helpful if you'd like to only call an API after the user has stopped typing for instance. The userTimeout function could be bound via onKeyUp to an input.
Not sure if this violates some good practice coding rule but I usually come out with this one:
if(typeof __t == 'undefined')
__t = 0;
clearTimeout(__t);
__t = setTimeout(callback, 1000);
This prevent the need to declare the timer out of the function.
EDIT: this also don't declare a new variable at each invocation, but always recycle the same.
Hope this helps.
Practical example Using Jquery for a dropdown menu !
On mouse over on #IconLoggedinUxExternal shows div#ExternalMenuLogin and set time out to hide the div#ExternalMenuLogin
On mouse over on div#ExternalMenuLogin it cancels the timeout.
On mouse out on div#ExternalMenuLogin it sets the timeout.
The point here is always to invoke clearTimeout before set the timeout, as so, avoiding double calls
var ExternalMenuLoginTO;
$('#IconLoggedinUxExternal').on('mouseover mouseenter', function () {
clearTimeout( ExternalMenuLoginTO )
$("#ExternalMenuLogin").show()
});
$('#IconLoggedinUxExternal').on('mouseleave mouseout', function () {
clearTimeout( ExternalMenuLoginTO )
ExternalMenuLoginTO = setTimeout(
function () {
$("#ExternalMenuLogin").hide()
}
,1000
);
$("#ExternalMenuLogin").show()
});
$('#ExternalMenuLogin').on('mouseover mouseenter', function () {
clearTimeout( ExternalMenuLoginTO )
});
$('#ExternalMenuLogin').on('mouseleave mouseout', function () {
clearTimeout( ExternalMenuLoginTO )
ExternalMenuLoginTO = setTimeout(
function () {
$("#ExternalMenuLogin").hide()
}
,500
);
});
This works well. It's a manager I've made to handle hold events. Has events for hold, and for when you let go.
function onUserHold(element, func, hold, clearfunc) {
//var holdTime = 0;
var holdTimeout;
element.addEventListener('mousedown', function(e) {
holdTimeout = setTimeout(function() {
func();
clearTimeout(holdTimeout);
holdTime = 0;
}, hold);
//alert('UU');
});
element.addEventListener('mouseup', clearTime);
element.addEventListener('mouseout', clearTime);
function clearTime() {
clearTimeout(holdTimeout);
holdTime = 0;
if(clearfunc) {
clearfunc();
}
}
}
The element parameter is the one which you hold. The func parameter fires when it holds for a number of milliseconds specified by the parameter hold. The clearfunc param is optional and if it is given, it will get fired if the user lets go or leaves the element. You can also do some work-arounds to get the features you want. Enjoy! :)
<!DOCTYPE html>
<html>
<body>
<h2>EJEMPLO CONOMETRO CANCELABLE</h2>
<button onclick="inicioStart()">INICIO</button>
<input type="text" id="demostracion">
<button onclick="finStop()">FIN</button>
<script>
let cuenta = 0;
let temporalTiempo;
let statusTime = false;
function cronometro() {
document.getElementById("demostracion").value = cuenta;
cuenta++;
temporalTiempo = setTimeout(cronometro, 500);
}
function inicioStart() {
if (!Boolean(statusTime)) {
statusTime = true;
cronometro();
}
}
function finStop() {
clearTimeout(temporalTiempo);
statusTime = false;
}
</script>
</body>
</html>

Categories

Resources