Why doesn't the setInterval function stop? - javascript

I'm trying to clear the time interval which runs every 15 seconds.
Here is the ajax request:
function extras()
{
$x = {
action:'extras'
};
var r;
$.ajax({
type:'POST',
url:'services.php',
data:$x,
beforeSend:function() {
$('input[name="stop_"]').trigger("click");
},
success:function(response) {
r = response;
//console.log(response)
},
complete:function() {
console.log(r);
$('input[name="re_start"]').trigger("click");
}
});
}
So, in my buttons re_start and stop_ i have:
$('input[name="re_start"]').click(function (event) {
event.preventDefault();
clearInterval(check);
var check = setInterval(function() {
extras();
},15000);
console.log('Starting again...');
});
$('input[name="stop_"]').click(function (event) {
event.preventDefault();
clearInterval(check);
console.log('Stop');
});
In my DOM in jQuery I initialize the function extras() and keep it in a variable called "check" where I initialize the time interval as follows:
<input type="button" style="display:none;" name="re_start">
<input type="button" style="display:none;" name="stop_">
<script type="text/javascript">
(function() {
extras();
var check = setInterval(function() {
extras();
},15000);
})();
function extras()
{
$x = {
action:'extras'
};
var r;
$.ajax({
type:'POST',
url:'services.php',
data:$x,
beforeSend:function() {
$('input[name="stop_"]').trigger("click");
},
success:function(response) {
r = response;
//console.log(response)
},
complete:function() {
console.log(r);
//message_smart(r);
$('input[name="re_start"]').trigger("click");
}
});
}
</script>
Then I can not understand how it is possible that the first 30 seconds work and when they pass 60 seconds seem to start doing things twice at once, then three and so on! It seems like if I change the interval every second and will run faster and faster. What is the problem?

The problem is here:
(function() {
extras();
var check = setInterval(function() {
extras();
},15000);
})();
You are creating a variable check in a new function scope that is inaccessible outside of that scope. Microsoft has a good example of scope in javascript. Additionally you can see this question.
Now to solve your problem you need to put the check variable in the global scope so remove the function wrapper.
extras();
var check = setInterval(function() {
extras();
},15000);
You also need to change the restart handler to reassign the variable, like so:
$('input[name="re_start"]').click(function (event) {
event.preventDefault();
clearInterval(check);
check = setInterval(function() {
extras();
},15000);
console.log('Starting again...');
});
Now they should all be using the same check variable and work as expected when clearing the timeout.

Related

clearInterval() not working and returns no errors

I would like to run a function, when a checkbox is checked and stop that function, when the checkbox is not checked.
This is how I tried it:
$('#auto').on('click', function() {
if ($(this).is(':checked')) {
// Interval
var autoInterval = window.setInterval(function() {
navi('next');
}, 1500);
}
else {
clearInterval(autoInterval);
}
});
The problem is clearInterval() does not work and I get no errors.
https://jsfiddle.net/n339tzff/9/
It will work if my code looks like this:
// Interval
var autoInterval = window.setInterval(function() {
navi('next');
}, 1500);
// Auto Play
$('#auto').on('click', function() {
if ($(this).is(':checked')) {
autoInterval;
}
else {
clearInterval(autoInterval);
}
});
But then I have another problem... I only want to run the function navi('next') when I click on the checkbox and not at the beginning.
When you click, it calls the setInterval and stores the result of the call in the autoInterval and after ending the function removes it. So you store and lost the value of your variable every time in the same call.
Declare the autoInterval variable outside of the event handler, to make it independent from the event handler's scope. Also you can wrap your function with a IIFE to not mutate this variable outside
(function() {
var autoInterval;
$('#auto').on('click', function() {
if ($(this).is(':checked')) {
autoInterval = window.setInterval(function() {
navi('next');
}, 1500);
} else {
clearInterval(autoInterval);
}
});
})();
You should define autoInterval outside of the event handler function, as after the event has run this variable would be 'discarded'/un-accessable.
var autoInterval = null;
$('#auto').on('click', function () {
if ($(this).is(':checked')) {
autoInterval = window.setInterval(function () {
navi('next');
}, 1500);
}
else if(autoInterval !== null) {
clearInterval(autoInterval);
autoInterval = null;
}
});

Disable timer within setInterval function with dynamic parameters

I wanted to pass dynamic parameters into a setInterval function (see question here) and specifically #tvanfosson's comment.
But now, I also want to disable that timer if a certain condition is met. I tried to define the timer variable as a global variable but I still get the timer as a undefined on this line:
console.log('else. timer=' + timer);:
else. timer=undefined
<script language="javascript" type="text/javascript">
var timer;
var params={};
params.color='light';
$(document).ready(function () {
timer=createInterval(showSmallWidget, params.color, 500);
});
function createInterval(f, dynamicParameter, interval) {
setInterval(function () {
f(dynamicParameter);
}, interval);
}
function showSmallWidget(color) {
if ($('#widget').html() == '') {
//do stuff
}
else {
console.log('else. timer=' + timer);
if (timer) { console.log('CLEAR TIMER'); timer.clearInterval(); timer = null; }
}
}
</script>
I tried to create a JSFiddle, but I can't get it to work properly: https://jsfiddle.net/puhw3z2k/
There are a couple problems:
1) You have to return the timerID from your createInterval() function:
function createInterval(f, dynamicParameter, interval) {
return setInterval(function () {
f(dynamicParameter);
}, interval);
}
2) clearInterval() works like this clearInterval(timer), not timer.clearInterval().

Dynamically added function still running even after remove from DOM

This script has been added dynamically. It has a timeout function, means that it runs every 5 seconds.
dynamicjs.php
$(document).ready(function(){
(function( $ ){
$.fn.baslatmesajlari = function() {
setInterval(function(){
console.log("I am running");
}, 5000);
return this;
};
})( jQuery );
});
$("body").baslatmesajlari();
I load this function to a div using;
$("#temporarycontent").load("dynamicjs.php");
And when I do
$("#temporarycontent").empty();
The script is still running. How can I stop it run ?
You can't, you need a handle to the intervalId returned by the setInterval function or provide an API on the plugin in order to destroy it and cleanup after itself. The easiest way would be to attach the state of the plugin to the DOM element on which it was applied.
(function ($) {
const PLUGIN_NAME = 'baslatmesajlari';
function Plugin($el) {
this.$el = $el;
this._timerId = setInterval(function () {
console.log('running');
}, 2000);
}
Plugin.prototype.destroy = function () {
this.$el.removeData(PLUGIN_NAME);
clearInterval(this._timerId);
};
$.fn[PLUGIN_NAME] = function () {
if (!this.data(PLUGIN_NAME)) this.data(PLUGIN_NAME, new Plugin(this));
return this;
};
})(jQuery);
$(function () {
var plugin = $('#plugin').baslatmesajlari().data('baslatmesajlari');
$('#destroy').click(function () {
plugin.destroy();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="plugin"></div>
<button id="destroy">Destroy plugin</button>
You must have a reference to the interval id, then, when you want to stop it's execution, call clearInterval(the_id)
let interval = null //this is the variable which will hold the setInterval id
$(document).ready(function () {
(function ($) {
$.fn.baslatmesajlari = function() {
interval = setInterval(function () {
console.log('I am running')
}, 5000)
return this
}
})(jQuery)
})
$("body").baslatmesajlari()
And then:
$("#temporarycontent").empty();
clearInterval(interval) // it should stop the function.
Hope it helps.

DIV should be refreshed only once

success: function (result) {
if (result == 1) {
var auto_refresh = setInterval(function () {
$('#myDiv').fadeOut('slow', function () {
$(this).load('/echo/json/', function () {
$(this).fadeIn('slow');
});
});
}, 1025544);
}
}
Friends on success function I have to refresh the myDiv DIV only once but as the above code the DIV is keep on fade out and fade in continuously instead it should work only once
setInterval() repeatedly calls a function or executes a code snippet, with a fixed time delay between each call. It will continue to do so until clearInterval is called.
It is easiest just to use setTimeout(), which just delays the function being called for the specified time:
var auto_refresh = setTimeout(function() {
$('#myDiv').fadeOut('slow', function() {
$(this).load('/echo/json/', function() {
$(this).fadeIn('slow');
});
});
}, 1025544);
using a variable name auto_refresh kind of indicates you want it to repeat. also -> 1025544ms = 17mins. so it will refresh every 17 mins.
if you want it to not show, wait 17mins then show, use #Jacod Grays Answer.
if you just want it to show, remove the setInterval like so :-
success: function (result) {
if (result == 1) {
$('#myDiv').fadeOut('slow', function () {
$(this).load('/echo/json/', function () {
$(this).fadeIn('slow');
});
});
}
}

setTimeout with ajax calls

<script type="text/javascript">
var timeOutID = 0;
var checkScores = function() {
$.ajax({
url: "<?php echo 'http://127.0.0.1/ProgVsProg/main/countScoreCh'?>",
success:function(response){
if (response !=' ') {
$('#scoreCh').html(response);
clearTimeout(timeOutID);
} else{
timeOutID = setTimeout(checkScores, 3000);
}
});
}
timeOutID = setTimeout(checkScores,1000);
</script>
I am using setTimeout if there is a change in the database. If there is a change..it will output the change.
My problem is setTimeout will only display the first call.and never checks again if there is another change in the database.
I don't know if setTimeout is the correct way of doing it.
Yeah, setTimeout only runs once though. You're looking for setInterval.
<script type="text/javascript">
var timeOutID = 0;
var checkScores = function() {
$.ajax({
url: "<?php echo 'http://127.0.0.1/ProgVsProg/main/countScoreCh'?>",
success: function(response) {
if(response !== '') {
$('#scoreCh').html(response);
}
}
});
};
timeOutID = setInterval(checkScores, 1000);
</script>
You could also get it working by just getting rid of that else in your success function:
success: function(response) {
if(response !== '') {
$('#scoreCh').html(response);
}
timeOutID = setTimeout(checkScores, 3000);
},
error: function() {
timeOutID = setTimeout(checkScores, 3000);
}
You are making these mistakes
If you want to poll for database changes, don't use setTimeout. Instead use setInterval and clear this interval depending upon your logic like after 50times or something else.
Use a busyFlag because you are making an asynchronous call. (As suggested by #mike)
Try this
var intervalId = null;
var IS_BUSY_FETCHING_UPDATES = false;
var checkScores = function() {
if (!IS_BUSY_FETCHING_UPDTAES) {
IS_BUSY_FETCHING_UPDTAES = true;
$.ajax({
url: "http://127.0.0.1/ProgVsProg/main/countScoreCh"
}).done(function(response){
if (response) {
$('#scoreCh').html(response);
}
}).fail(function(e) {
console.error(e);
}).always(function() {
IS_BUSY_FETCHING_UPDATES = false; // This will be executed when AJAX gets complete
});
}
intervalID = setInterval(checkScores,1000);

Categories

Resources