How can I break a loop when I'm out of it? - javascript

Here is my code:
$(document).on('click', '.fa-search', function () {
while(1) {
magnifire.fadeTo('slow', 0.2).fadeTo('slow', .8);
}
sendAjaxRequest();
// Here I need to break (stop) that while loop
})
As I've commented in my code, I need to stop while(1) after sendAjaxRequest(); executed. How can I do that?

You could use setInterval and clearInterval for this. As their names suggest, setInterval sets a function to execute repeatedly at given interval (1000 ms in example below), and clearInterval stops all further executions.
var interval = setInterval(function() {
console.log("Do something");
// magnifire.fadeTo('slow', 0.2).fadeTo('slow', .8);
},1000);
function Clear() {
clearInterval(interval);
console.log("Stop iterating");
}
<button onclick="Clear()">Click me</button>

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.

setTimeout and setInterval on same function(with parameters)

I want to set a timeout and an Interval as an onmousedown eventhandler for this function.
function start(clicked_className,clicked_classValue)
{
add(clicked_className,clicked_classValue);
}
startInter=setInterval(start.bind(null,y.className, y.value.replace(/\s/g, '')),600);
That's what I have as working Interval, but don't know how to add timeout without it being 2 separate things. I want the Interval to have a timeout.
You can just put setInterval inside setTimeout function, something like:
el.onmousedown = function() {
start(...)
setTimeout(function(){
// start(...) // maybe also here?
setInterval(function(){
start(...)
},1000)
},5000)
}
setTimeout(function()
{
setInterval(start.bind(null,y.className, y.value.replace(/\s/g, '')),400);
},1000);
worked

Javascript ClearTimeout doesnt work

I'm looking for a solution for my code. My clearTimeout function doesn't work in the stop(); and start(); functions, does anybody know how to fix this?
The stop, start and reset button have all a setTimeout function. What I would like to do is that if is clicked at one of the buttons, the other two buttons have cleartimeout. But for somehow it doesn't working right now.
var isTimerStarted;
var timeOutElse;
var timeOut;
var opnieuw;
function start() {
clocktimer = setInterval("update()", 1);
x.start();
isTimerStarted = true;
timeOutElse = setTimeout(function(){
document.getElementById("scherm3").style.display = "block";
document.getElementById("scherm2.2").style.visibility = "hidden";
}, 8000)
}
function stop() {
x.stop();
clearInterval(clocktimer);
isTimerStarted = false;
timeOut = setTimeout(function(){
document.getElementById("scherm4").style.visibility = "visible";
document.getElementById("scherm2.2").style.visibility = "hidden";
}, 4000)
}
function reset() {
stop();
x.reset();
update();
opnieuw = setTimeout(function(){
document.getElementById("scherm3").style.display = "block";
document.getElementById("scherm2.2").style.visibility = "hidden";
}, 10000);
clearTimeout(timeOut);
clearTimeout(timeOutElse);
document.getElementById("buttontimer").value = "Start";
}
setTimeout(start, 5000);
function toggleTimer(event) {
if (isTimerStarted) {
stop();
event.target.value = 'Start';
clearTimeout(opnieuw);
clearTimeout(timeOutElse);
} else {
start();
event.target.value = 'Stop';
clearTimeout(opnieuw);
clearTimeout(timeOut);
}
}
There's nothing wrong with your code, from what I can tell.
But I think you might have forgot to remove a line from it.
setTimeout(start, 5000); is creating timeouts after 5 seconds whatever/whenever you click a thing.
It is what could create timing issues.
Here's a scenario that could happen:
you click
toggleTimer() -> start() -> create timeout and interval
5s later your setTimeout(start, 5000) executes and reassign your timeout and interval variables
you re-click
latest timeout and interval gets cleared, but not the first ones
Just to be safe, you could clear, at the beginning of each of your functions, the timeouts and intervals you're creating in the said function.
This way, you will always clear timeouts and intervals that gets created.

How can I depend on the interval that I just cleared in jquery?

It's a follow up to this question - https://stackoverflow.com/a/33430608/3766930
Basically I have a text area and when user starts typing in sth, the counter starts going down from 3 to 0. when it reaches 0 it gets disabled.
Now I want to add a feature of starting over - when user clicks the link start over, text area goes enabled again and user has 3 seconds (again) to perform the input.
I modified the jquery script:
$('#textArea').on('input propertychange', display30Seconds);
var interval;
function display30Seconds() {
var validTime = 3000;
if (!interval)
interval = setInterval(function () {
$('#counter').html(validTime / 1000);
validTime = validTime - 1000;
if (validTime < 0) {
clearInterval(interval);
alert('Time Up!');
$('#textArea').prop('disabled', true);
$('#counter').html('start over');
$('#counterIsDone').on('click', function(){
$('#textArea').prop('disabled', false);
display30Seconds();
});
}
}, 1000);
}
but I see that I cannot call the method display30Seconds(); again. Or rather I can, but the interval is not set again. How can I fix it?
Seems like I'm not entering the code inside
if (!interval)
because the interval is not visible any more after clearing it (?). So I thought about moving the var interval; into the body of the method function display30Seconds() {, but that doesn't bring the expected effect. Is there a way of fixing it?
Here is my updated fiddle: http://jsfiddle.net/jf4ea4nx/3/
Set interval=null after the clearInterval() call.
What seems to confuse you is the semantics of clearInterval(interval). As Patrick Evans points out in his comment, it will not set interval to a value that evaluates to false in a condition.
To make it completely clear you could use a boolean variable such as countdownRunning in addition to the interval variable to keep track of whether the countdown is active or not.
Try this:
$('#textArea').on('input propertychange', display30Seconds);
var interval=false;
function display30Seconds() {
var validTime = 3000;
if (!interval)
interval = setInterval(function () {
$('#counter').html(validTime / 1000);
validTime = validTime - 1000;
if (validTime < 0) {
clearInterval(interval);
alert('Time Up!');
$('#textArea').prop('disabled', true);
$('#counter').html('start over');
$(document).on('click','#counterIsDone', function(){
$('#textArea').prop('disabled', false);
display30Seconds();
});
interval=false;
}
}, 1000);
}
You can improve your code by using a conditional recursive call to to your iterative function instead - each call has a one second delay, which makes it slightly more intuitive to use (think of each call as one tick):
var seconds = 3;
$('#textArea').on('input propertychange', setTimeout(timeout.bind(null, seconds), 1000));
function timeout (iterations) {
$('#counter').html(iterations);
if (iterations === 0) {
alert('Time Up!');
$('#textArea').prop('disabled', true);
$('#counter').html('start over');
$('#counterIsDone').on('click', function(){
$('#textArea').prop('disabled', false);
timeout(seconds);
});
}
else {
setTimeout(timeout.bind(null, --iterations), 1000);
}
}
The bind function simply binds the arguments of the bind function to the arguments of the timeout call - the first argument to the bind function declares its this scope; but don't worry about that too much.
You can modify the duration of the timer by changing the seconds var. Hope this helps :)

delay the on("click") event

I have this code
$("input").on('keyup', function () {
$("block"),slideDown("slow")......
The problem is taht when I write fast the block will do the "animation" again and agin much slower than I write
Is there another event I can use to only run the code "after I'm finished writing" lets say, I stop writing and then it taks 500ms and then the code is executed.
function throttle(fn, time ){
var timer = 0;
return function() {
clearTimeout(timer);
timer = setTimeout($.proxy(fn, this), time);
};
}
$("input").on('keyup', throttle(function () {
$("block").slideDown("slow")
},500));
The throttle returns a new function that calls the old function once 500 milliseconds have elapsed since the function was last called.
Something like this is what I've used before:
$(input).keyup(onKeyUp);
/**
* Handler for the keyup event
*/
function onKeyUp() {
//reset
clearTimeout(myTimer);
myTimer = setTimeout(otherFunction, 500);
}
Now otherFunction will be called after 500 milliseconds, but on each keyup event this timer will be reset.
Try to use...
function slideDown(){
...
}
// call
setTimeout(function(){ slideDown(); }, 1000);

Categories

Resources