Clear setTimeouts applied by class.each operation that creates timeout - javascript

I'm sorry the title might not make much sense. I'm not sure how to word what i'm doing.
I have a class that I add to elements that uses HTML5 data attributes to setup a refresh timer. Here is the current code.
$(document).ready(function () {
$('.refresh').each(function() {
var element = $(this);
var url = element.data('url');
var interval = element.data('interval');
var preloader = element.data('show-loading');
var globalPreloader = true;
if (typeof preloader === 'undefined' || preloader === null) {
}
else if (preloader != 'global' && preloader != 'true') {
globalPreloader = false;
}
(function(element, url, interval) {
window.setInterval(function () {
if (!globalPreloader)
{
$('#' + preloader).show();
}
$.ajax({
url: url,
type: "GET",
global: globalPreloader,
success: function (data) {
element.html(data);
if (!globalPreloader) {
$('#' + preloaderID).hide();
}
}
});
}, interval);
})(element, url, interval);
});
$.ajaxSetup({ cache: false });
});
Now I have elements that a user can click on the 'window' which removes it.
These elements can be tired to a timer that was set by the above code.
Code used to remove the element
$(".btn-close").on('click', function () {
var id = $(this).closest("div.window").attr("id");
if (typeof id === 'undefined' || id === null) {
} else {
$('#' + id).remove();
}
});
I need to now kill the timers created for the elements removed.
What is the best way to do this?

Not clear on how you clear them so I do them all here at the end.
$(document).ready(function () {
$('.refresh').each(function () {
var element = $(this);
var url = element.data('url');
var interval = element.data('interval');
var showLoading = element.data('show-loading');
var preloaderID = element.data('preloader-id');
if (typeof showLoading === 'undefined' || showLoading === null) {
showLoading = true;
}
(function (element, url, interval) {
var timerid = window.setInterval(function () {
if (showLoading) {
$('#' + preloaderID).show();
}
$.ajax({
url: url,
type: "GET",
global: showLoading,
success: function (data) {
element.html(data);
if (showLoading) {
$('#' + preloaderID).hide();
}
}
});
}, interval);
element.data("timerid",timerid );//add the timerid
})(element, url, interval);
});
$.ajaxSetup({
cache: false
});
$('.refresh').each(function () {
var timerId = $(this).data("timerid");
window.clearInterval(timerId);
});
});
Example: remove timer on a click
$('.refresh').on('click', function () {
var timerId = $(this).data("timerid");
window.clearInterval(timerId);
});

window.setIntervalreturns a handle for the timeout. You can use that to stop the timeout:
var handle = window.setInterval(function() {
window.clearInterval(handle);
}, 1000);
Hope that helps.

Here's a little demo of intervals and "interval assassins". It's a minimal example showing how you can clear intervals in a JavaScript-y way.
$('.start').click(function() {
var $parentRow = $(this).closest('tr')
var $stop = $parentRow.find('.stop')
var $val = $parentRow.children('.val')
// interval
var iid = setInterval(function() {
$val.text(+$val.text() + 1)
}, 10)
console.log(`New Target: ${iid}`)
// interval assassin
$stop.click(function() {
clearInterval(iid)
console.log(`Interval[${iid}] has been assassinated.`)
$(this).off('click')
})
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td><button class="start">Start</button></td>
<td><button class="stop">Stop</button></td>
<td class="val">0</td>
</tr>
<tr>
<td><button class="start">Start</button></td>
<td><button class="stop">Stop</button></td>
<td class="val">0</td>
</table>
Just run the snippet to see a demo. Feel free to comment if you have any questions. You can set up multiple intervals by pressing start repeatedly and have them all be cleared at once with a single click of stop.

Related

How do i stop this code from executing using a stop button

I have a start button which triggers a function.
<button type="button" onclick="start()">START</button>
Here is my java script
function start() {
var cookieValue = document.getElementById('balance').getAttribute('value');
if (cookieValue == 0){
alert("insufficient funds");
exit();
}else{
var url = $("#url").val() + '.php?check=';
console.log(url);
var line = $("#ccs").val();
var linesend = line.split("\n");
linesend.forEach(function(value, index) {
setTimeout(
function start() {
Array.prototype.randomElement = function () {
return this[Math.floor(Math.random() * this.length)]
}
$.ajax({
url: url + value,
type: 'GET',
async: true,
success: function(result) {
if (result.match("success")) {
removeline();
live(result);
}else {
removeline();
dead(result);
}
}
});
},2500 * index);
});
}
}
How do I stop this 2500 * index loop right here using a stop function? Cause I wanted a stop button for this one
Clear timeout?
var timeout = setTimeout(start, 2500*index);
clearTimeout(timeout);

Compare data returned from AJAX with div data

I would like to compare data to determine if the div needs to be reloaded.
// <![CDATA[
$(function () {
function reload (elem, interval) {
var $elem = $(elem);
var $original = $elem.html();
$.ajax({
cache : false,
url : '/inbox-header.php',
type : 'get',
success : function (data) {
var result = $.trim(data);
var resu = $.trim($original);
console.log(result);
if (result == resu) {
alert('a');
setTimeout(function () {
reload(elem, interval)
}, interval);
return;
}
$elem.html(data);
setTimeout(function () {
reload(elem, interval)
}, interval);
}
});
}
reload('#inboxheader', 500);
});
// ]]>
When I show the output in the console it looks the same, but the alert never shows, so its always false.
UPDATE:
The output of those variables can be found here, unable to post them here..
http://pastebin.com/abfCk7pH
I dont know why but the trim function did not do his job.
this works:
$(function() {
function reload(elem, interval) {
var $elem = $(elem);
var $original = $elem.html();
$.ajax({
cache: false,
url: '/inbox-header.php',
type: 'get',
success: function(data) {
var opgehaaldedata = data.replace(
/(\r\n|\n|\r)/gm, "");
var orgineledata = $original.replace(
/(\r\n|\n|\r)/gm, "");
if (opgehaaldedata == orgineledata) {
//alert('a');
setTimeout(function() {
reload(elem, interval)
}, interval);
return;
} else {
$elem.html(opgehaaldedata);
setTimeout(function() {
reload(elem, interval)
}, interval);
return;
}
}
});
}
reload('#inboxheader', 500);
});

Multiple calls to Ajax instead of once

I have the following code which works fine for most cases, but the problem I am having is on mouse over . After you hover for 10 sec the content expands and then calls ajax. The Ajax is making calls 5 times instead of just once.
I am not sure why its keep calling 5 times. Can someone help me fix this so ajax call runs only once?
Here is my code snippet below and the full working fiddle demo is here
$(".previewCard-content").hide();
var timeo = null;
$("body").on("mouseenter", ".previewCard-showhide", function() { // Use rather mouseenter!
var $that = $(this); // Store the `this` reference
clearTimeout(timeo); // Clear existent timeout on m.Enter
timeo = setTimeout(function() { // Before setting a new one
$that.hide().closest('p').next(".previewCard-content").slideDown("slow");
/**************** AJAX CALL********************/
var LinkTextVal = $that.closest('.previewCard-b').find('.previewCardPageLink').text();
console.log(" LinkTextVal " + LinkTextVal);
var descPageName = LinkTextVal + ' | About';
if ($('#userID').val() !== '' && $('#userID').val() !== undefined && $('#userID').val() !== null) {
$.ajax({
url: '/localhost/biz/actions/searchBookmark' + '?cachestop=' + nocache,
type: "get",
data: {
bookmarkName: descPageName
},
success: function(response) {
if (response === true) {
$that.parents('.previewCard-b').find('.save a').addClass('saved');
$that.parents('.previewCard-b').find('.save a').addClass('active');
$that.parents('.previewCard-b').find('.save a').find(".action-text").text("Saved");
}
},
error: function(e) {
console.log('Unable to check if a bookmark exists for the user.');
}
});
}
/***************** END AJaX/SAVE BUTTON ************/
}, 1000);
}).on("mouseleave", ".previewCard-showhide", function() { // mouse leaves? Clear the timeout again!
clearTimeout(timeo);
});
$(".close-btn").on("click", function() {
var $itemB = $(that).closest(".previewCard-b");
$itemB.find(".previewCard-content").slideUp();
$itemB.find(".previewCard-showhide").show();
});
Mouse hover events happen every time the mouse moves over the element. You need is to have a boolean which checks if you have sent the AJAX Request or not, and if it hasn't send the AJAX request, else ignore the event.
$(".previewCard-content").hide();
var timeo = null;
var ajaxSent = false
$("body").on("mouseenter", ".previewCard-showhide", function() { // Use rather mouseenter!
var $that = $(this); // Store the `this` reference
clearTimeout(timeo); // Clear existent timeout on m.Enter
timeo = setTimeout(function() { // Before setting a new one
$that.hide().closest('p').next(".previewCard-content").slideDown("slow");
/**************** AJAX CALL********************/
var LinkTextVal = $that.closest('.previewCard-b').find('.previewCardPageLink').text();
console.log(" LinkTextVal " + LinkTextVal);
var descPageName = LinkTextVal + ' | About';
if ($('#userID').val() !== '' && $('#userID').val() !== undefined && $('#userID').val() !== null && !ajaxSent) {
ajaxSent = true;
$.ajax({
url: '/localhost/biz/actions/searchBookmark' + '?cachestop=' + nocache,
type: "get",
data: {
bookmarkName: descPageName
},
success: function(response) {
if (response === true) {
$that.parents('.previewCard-b').find('.save a').addClass('saved');
$that.parents('.previewCard-b').find('.save a').addClass('active');
$that.parents('.previewCard-b').find('.save a').find(".action-text").text("Saved");
}
},
error: function(e) {
console.log('Unable to check if a bookmark exists for the user.');
}
});
}
/***************** END AJaX/SAVE BUTTON ************/
}, 1000);
}).on("mouseleave", ".previewCard-showhide", function() { // mouse leaves? Clear the timeout again!
clearTimeout(timeo);
});
$(".close-btn").on("click", function() {
var $itemB = $(that).closest(".previewCard-b");
$itemB.find(".previewCard-content").slideUp();
$itemB.find(".previewCard-showhide").show();
});

jQuery animations not being actioned correctly

Can I get fresh eyes on what's happening here, please?
The function is supposed to be: Check for new data, if new > fade out > reload > fade in, if it's not new data don't animate. However now it's fading out and in everytime it checks for new data, which it wasn't doing when I had have it open in dev.
$(function() {
function reload(elem, interval) {
var $elem = $(elem);
var $original = $elem.html();
$.ajax({
cache: false,
url: 'track.php',
type: 'get',
success: function(data) {
if ($original == data) {
setTimeout(function() {
$("#air_track").fadeOut();
reload(elem, interval)
$("#air_track").fadeIn("slow");
}, interval);
return
}
$elem.html(data);
setTimeout(function() {
reload(elem, interval)
}, interval)
}
})
}
reload('#air_track', 5000)
});
Keep it in mind I've been up for 20+ hours with little sleep so it may actually be really obvious.
Try to use the DRY principle - don't repeat yourself.
Set the timeout regardless of data each time, and perform the animation inside the if:
$(function() {
var reload = function(elem, interval) {
var $el = $(elem);
$.ajax({
cache: false,
url: 'track.php',
type: 'get',
success: function(data) {
var html = $.parseHTML(data);
var newText = $(html).text().trim();
var current = $el.find('span').text().trim();
if (current != newText) {
$el.fadeOut(function() {
$el.html(data).fadeIn('slow');
});
}
setTimeout(function() {
reload(elem, interval);
}, interval)
}
});
};
reload('#air_track', 5000);
});

How to stop interval function

I'm trying to stop with return syntax:
<script>
$(document).ready(function() {
setInterval(function() {
var url = "../view/anychange.php";
$.getJSON(url, function(data) {
f(data.exists == 0){
alert("0");
} else {
alert("1");
return;
}
});
}, 5000);
});
</script>
The function verifies every 5 seconds if there exists data in my table.
I need to stop the function when data.exists == 1 ( the alert("1") ).
<script>
$(document).ready(function() {
var id;
id = setInterval(function() {
var idRefCopy = id; // You need this otherwise you'll get a reference exception
var url = "../view/anychange.php";
$.getJSON(url, function(data) {
if(data.exists == 0){
alert("0");
} else {
alert("1");
clearInterval(idRefCopy);
return;
}
});
}, 5000);
});
</script>
You have to define the interval inside a variable, and then clear it. Try this:
<script>
$(document).ready(function() {
var interval = setInterval(function() {
var url = "../view/anychange.php";
$.getJSON(url, function(data) {
if(data.exists == 0){
alert("0");
} else {
clearInterval(interval);
}
});
}, 5000);
});
</script>
You have a typo in the code (i have fixed it here, its a "f" instead of "if" ;) Hope this helps.
You need to clear your interval, this will prevent your function from being fired again. See this for interval reference.
This should be your code:
$(document).ready(function() {
var i = setInterval(function() {
var url = "../view/anychange.php";
$.getJSON(url, function(data) {
f(data.exists == 0) {
alert("0");
} else {
alert("1");
clearInterval(i);
}
});
}, 5000);
});
How about clearInterval?
var myVar = setInterval(function(){myTimer()},1000);
function myTimer()
{
var d = new Date();
var t = d.toLocaleTimeString();
document.getElementById("demo").innerHTML=t;
}
function myStopFunction()
{
clearInterval(myVar);
}
source: W3Schools
I strongly suggest you do not hit your server unless you know your ajax was done
This example will check, but only after the server returned
var counter = 0;
function checkData() {
var url = "../view/anychange.php";
$.getJSON(url, function(data) {
if (data.exists == 0) {
$("#someContainer").html("Not yet on attempt #"+(counter++));
setTimeout(checkData,5000);
} else {
$("#someContainer").html("found on attempt #"+(counter++));
}
});
}
$(function() {
checkData();
});

Categories