Perform action before given interval in setInterval has passed - javascript

is there an option to check whether user performed an action during the interval? For example, I have elements which highlight randomly one by one with the interval 1000ms. And I should click on the active element during the interval. How to check whether I was successful ?

I have implemented something which might be what you are thinking of:
const start = document.querySelector('#start');
const clickme = document.querySelector('#clickme');
start.addEventListener('click', function(){
clickme.disabled = false;
setTimeout(function(){
clickme.disabled = true;
}, 1000);
});
clickme.addEventListener('click', function(){
alert('Yo!');
});
<button id='start'>Start</button>
<button id='clickme' disabled>Click Me</button>

Related

Javascript increment value faster with mouse hold [duplicate]

This question already has answers here:
Incrementing value continuously on mouse hold
(5 answers)
Closed 5 years ago.
I have this script that adds 1 to a value every time I click on a button:
<script>
function incrementValue(id) {
var value = parseInt(document.getElementById(id).innerHTML);
value = value + 1;
document.getElementById(id).innerHTML = value;
}
</script>
<button onclick="incrementValue('skill_1')"> add </button><br>
<span id=skill_1>0</span>
However I want to adjust it so that if I hold down the mouse button, it'll repeat so I don't have to keep pressing it over and over.
Any way to do that using javascript? Or would jquery suit?
To achieve this you need to use the mousedown event to start a timeout (which is the delay before the incremental count starts) and an interval (which does the repeated counting). You'll also need a mouseup and mouseleave handler to remove both of those timers. Try this:
var timeout, interval;
[].forEach.call(document.querySelectorAll('.add'), function(button) {
button.addEventListener('mousedown', function() {
var id = button.dataset.target;
incrementValue(id);
timeout = setTimeout(function() {
interval = setInterval(function() {
incrementValue(id);
}, 50);
}, 300);
});
button.addEventListener('mouseup', clearTimers);
button.addEventListener('mouseleave', clearTimers);
function clearTimers() {
clearTimeout(timeout);
clearInterval(interval);
}
});
function incrementValue(id) {
var el = document.getElementById(id);
var value = parseInt(el.textContent, 10);
document.getElementById(id).textContent = ++value;
}
<button class="add" data-target="skill_1">add</button><br />
<span id="skill_1">0</span>
You'll need 3 event handler:
mousedown that will call a function, that will call itself with a timeout (continuosIncerment) while the mouse button is pressed.
mouseup that will clear the timeout when the button is released.
mouseleave that clears the timeout when the mouse leaves the button area.
const btn = document.querySelector('#btn');
const skill_1 = document.querySelector('#skill_1');
let value = 0;
let timer;
function continuosIncerment() {
skill_1.innerHTML = ++value;
timer = setTimeout(continuosIncerment, 200);
}
function timeoutClear() {
clearTimeout(timer);
}
btn.addEventListener('mousedown', continuosIncerment);
btn.addEventListener('mouseup', timeoutClear);
btn.addEventListener('mouseleave', timeoutClear);
<button id="btn"> add </button><br>
<span id="skill_1">0</span>
Instead of reading the value from the HTML, then writing it back, it's easier to hold the value in a variable, increment it, then write it out.
Did you know you can do this with a simple HTML spinner?
<input type="number" min="0" max="50" step="1">
I'd go with a solution like this: on mouse down event starts a repeating timer that triggers your function and it stops when the mouse up event occurs.
var inter = null;
function setInter(){
inter=setInterval(incrementValue, 500);
}
function unsetInter(){
clearInterval(inter);
}
function incrementValue() {
var value = parseInt(document.getElementById('skill_1').innerHTML);
value = value + 1;
document.getElementById('skill_1').innerHTML = value;
}
<button
onmousedown="setInter()"
onmouseup="unsetInter()"> add </button>
<br>
<span id=skill_1>0</span>

How to clear all running timeouts before setting a new timeout

When I click the mic icon two times simultaneously it comes back to inactive state but the timeout function still takes place.
Below are my console values :
true
false
false
Instead of:
true
false
How to prevent this from happening.
// Start listening on click.
var active= false;
var $mic = $("#mic-container");
$mic.click(function(event){
//event.preventDefault();
// if we're recording when the button is clicked
if(active) {
$mic.removeClass("active pulse");
active=false; console.log(active);
annyang.abort();
// if we're not recording when the button is clicked
} else {
annyang.start({ autoRestart: false, continuous: false }); // start listening
active = true; console.log(active); // set recording var to true
$mic.addClass('active pulse'); // turn on active class
setTimeout(function(){
$mic.removeClass("active pulse");
active=false; console.log(active);
annyang.abort();
}, 8000);
}
});
annyang.addCallback('resultNoMatch', function () {
$('.myErrorText').html('Try saying a valid command. See help section for a list of valid commands!');
$mic.addClass("result-no-match");
setTimeout(function(){
$mic.removeClass("active pulse result-no-match");
active=false; console.log(active);
annyang.abort();
}, 500);
});
annyang.addCallback('resultMatch', function () {
$('.myErrorText').text('');
$mic.addClass("result-match");
setTimeout(function(){
$mic.removeClass("active pulse result-match");
active=false; console.log(active);
annyang.abort();
}, 500);
});
Even i had the same kind of problem. Try this
// Start listening on click.
var timeoutHandle;
var active= false;
var $mic = $("#mic-container");
$mic.click(function(event){
//event.preventDefault();
if(active)
annyang.abort();
else
annyang.start({ autoRestart: false, continuous: false});
});
annyang.addCallback('start', function () {
active = true; console.log(active);
$mic.addClass('active pulse');
window.clearTimeout(timeoutHandle);
timeoutHandle = setTimeout(annyang.abort, 5000);
});
annyang.addCallback('end', function () {
window.clearTimeout(timeoutHandle);
timeoutHandle = setTimeout(function () {$mic.removeClass("active pulse result-match result-no-match");}, 200);
active=false; console.log(active);
});
annyang.addCallback('resultNoMatch', function () {
$mic.addClass("result-no-match");
$('.myErrorText').html('Try saying a valid command. See help section for a list of valid commands!');
});
annyang.addCallback('resultMatch', function () {
$('.myErrorText').text('');
$mic.addClass("result-match");
});
Assign the timeout to a variable and then just call the clearTimeout() method when you want to kill the timer. For example:
var resultMatchTimer = null;
// stops the timer
if(resultMatchTimer) {
clearTimeout(resultMatchTimer);
resultMatchTimer = null;
}
// starts the timer
resultMatchTimer = setTimeout(..., ...);
You should store the result (handle) of setTimeout in a var and call clearTimeout on that handle.
var timeoutHandle = setTimeout(...);
clearTimeout(timeoutHandle); // this will clear the timeout.
With the correct scoping, you can call clearTimeout from all your clicks, and decide you need 3 handles to clear them individually or just use one form all setTimeouts and just clear it. When een new setTimeout is called your handle will be overwritten so make sure your clear the other timeout before that.
The problem is that timeouts are being started while those from previous clicks are still counting.
You're going to have to keep track of the active timeouts, and cancel them if they're running while the user clicks again.
This is possible because setTimeout returns an identifier you can pass to clearTimeout to, as the function name suggests, cancel the timeout.
For example:
var resultMatchTimeout; // Variable to store a reference to a timeout in.
annyang.addCallback('resultMatch', function () {
$('.myErrorText').text('');
$mic.addClass("result-match");
if(resultMatchTimeout){ // If a timeout is running, cancel it.
clearTimeout(resultMatchTimeout);
resultMatchTimeout = null;
}
resultMatchTimeout = setTimeout(function(){ // Save a reference to the current timeout.
$mic.removeClass("active pulse result-match");
active=false; console.log(active);
annyang.abort();
}, 500);
});
You're going to have to do this for your other setTimeout calls too, obviously.
Just make sure to use different variables for each of the timeouts, otherwise, you 'll be cancelling the wrong timout.
One more thing to consider: set the active/not-active state based on the actual voice recognition engine state and not based on user clicks.
Check annyang.isListening()
Every setTimeout() returns a unique Id which could be used to clear the timeout using clearTimeout.
I can see that you have multiple timers running, so what you could do is store all the ids returned each time from setTimeout method in a array and use the same array to clear all the timers in a loop.
MDN reference: https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout
JS CODE:
var myVar;
function myFunction() {
myVar = setTimeout(function(){ alert("Hello"); }, 3000);
}
function myStopFunction() {
clearTimeout(myVar);
}
Note: This is just a generic solution, which can be a base for final/actual solution

onmouseover() to invoke onclick after 1 second?

I have an element:
<b onclick="alert('');" onmouseover="this.style.color='red'; setTimeout('........', 1000);" onmouseout="this.style.color='';">123</b>
I need that when element is mouseovered and after 1 second the mouse cursor continue staying above this element, then onclick() event of this element should start.
In other words, what should be instead of '..............' in onmouseover() event?
window.countdown = setTimeout(function(){this.click();}, 1000);
Additionally, you need to clear the interval in the mouseout handler:
clearTimeout(countdown);
Ideally you would give your element an ID and use the new event registration model:
var e = document.getElementById('myelement');
e.addEventListener('click',function(){
alert('');
});
e.addEventListener('mouseenter',function(){
var self = this;
this.style.color='red';
window.countdown = setTimeout(function(){self.click();}, 1000);
});
e.addEventListener('mouseleave',function(){
this.style.color='';
clearTimeout(countdown);
});
You should start the interval on mouse over event as a global variable to refer on mouse out event to clear it like #Asad said.
<b onclick = "alert()"
onmouseover = "window.countdown = setTimeout(function(){this.click();}, 1000);"
onmouseout = "clearTimeout(countdown)">
123
</b>
You'll have to do some extra work, and this won't work out very well for you inside of inline Javascript. This is all pseudocode so I don't recommend copy/pasting!
// We'll need to create an interval and store it
var timerInterval = {}
// And keep track of how many seconds have elapsed
var timeElapsedInSeconds = 0;
function tick (){
timeElapsedInSeconds++;
if (timeElapsedInSeconds > 0){
// YOUR GREAT CODE HERE
}
// Either way, let's be sure to reset everything.
resetTimer();
}
function hoverOverHandler (){
// Start our timer on hover
timerInterval = window.setInterval(tick, 1000);
}
function resetTimer () {
timeElapsedInSeconds = 0;
window.clearInterval(timerInterval);
}
function hoverOutHandler () {
// Kill timer on hoverout
resetTimer();
}
Ok, I did some trick with dynamic id and this is what came out:
<b style="color:red;" onclick="if(this.style.color!='green'){return false;}else{this.style.color='red';} alert(this.parentNode);" onmouseover="if(this.style.color!='green'){var newID='tmpID_'+Math.floor(Math.random() * (10000000)); if(this.id==''){this.id=newID;} setTimeout('top.document.getElementById(\''+this.id+'\').onclick();',1000); this.style.color='green';}" onmouseout="this.style.color='red';">click</b>
crossbrowsered =)

jquery combining each and setInterval on elements with shared class

I have a series of links with a class "bloglink".
They have a click event associated with them - but that is irrelevant at this point. I am trying to cycle through them and trigger the click event every X seconds. This is where I'm at:
$('a.bloglink').each(function(){
var $bl = $(this);
setInterval(function(){
$bl.trigger('click')
},2000);
})
But it just triggers the click event for all of them at once.
Any tips?
You could do something like this:
(​function Loop()​{
var arry = $("a.bloglink").get();
var traverse = function(){
$(arry.shift()).trigger('click');
if (arry.length)
setTimeout(traverse, 2000);
};
setTimeout(traverse,2000);
})();
You can see it in action here: http://jsfiddle.net/Shmiddty/B7Hpf/
To start it over again, you can just add an else case:
(​function Loop()​{
var arry = $("a.bloglink").get();
var traverse = function(){
$(arry.shift()).trigger('click');
if (arry.length)
setTimeout(traverse, 2000);
else
Loop(); // Do the whole thing again
};
setTimeout(traverse,2000);
})();
See here: http://jsfiddle.net/Shmiddty/B7Hpf/1/
Create a function that sets the timer to run your code, clears the timer, then calls itself on the next element...
function processNext($current)
{
$h = setInterval(function() {
$current.css('color', 'green');//do your business here
clearTimeout($h);
if ($current.next('a.blah').size()>0)
{
processNext($current.next('a.blah'));
}
}, 750);
}
processNext($('a.blah').eq(0));
See here: http://jsfiddle.net/skeelsave/6xqWd/2/

Onclick button timeout javascript

Can someone help me get started with a button timeout feature. All I want is a button (when clicked) it becomes inactive for 2 seconds. After which it is active again.
<input type="button" value="click" id="click" onclick="foo(this);"/>​
function foo(obj) {
obj.disabled = true;
setTimeout(function() {
obj.disabled = false;
}, 2000);
}​
LIVE DEMO
window.setTimeout on MDN:
Executes a code snippet or a function after specified delay.
Start of with:
<button>Click me!</button>
Add an event:
<button onClick="...">Click me!</button>
Now we need to put something in place of that ....
this can be used to mean "the button that was just clicked"
this.disabled can be set to true or false to disable (or re-enable) the button.
setTimeout(function() {...},2000); executes the anonymous function after two seconds have passed (or as near as the timer resolution allows).
Again, need to put something in the .... I've already told you how to re-enable the button.
Although, since this isn't terribly reliable inside anonymous functions, it's probably better to start with var t = this; and use t to mean the button.
With all that in place, you have:
<button onClick="var t = this; t.disabled = true; setTimeout(function() {t.disabled = false;},2000);">Click me!</button>
Done. I hope this explanation was helpful.
PS. To those who are against inline event handlers:
This is an example
The OP is a beginner
An inline event is good enough
The function setTimeout allows you to specify a function to be called after an amount of milliseconds has passed. In this case, I passed in an anonymous function, that is, a function that does not have a name that is used for the sole purpose of re-enabling my button after 2 seconds.
var mybutton = document.getElementById("mybutton");
mybutton.onclick = function() {
mybutton.disabled = true;
setTimeout(function() {
mybutton.disabled = false;
}, 2000);
};​
Live example
You can use setTimeout() function in javascript. Something like
<html>
<head></head>
<body>
<input id="test" type="submit" value = "clickme" onclick="deactivatefunc()">
<script type="text/javascript">
function deactivatefunc()
{
var btn = document.getElementById("test");
btn.disabled = true;
var mytimer = setTimeout(activate,2000);
}
function activate () {
var btn = document.getElementById("test");
btn.disabled = false;
}
</script>
</body>
</html>

Categories