Pause in middle of javascript function - javascript

I am trying to pause in the middle of a function for a given period of time (5 secs)
this is what I tried, but It doesn't work
(function MessagesAjax() {
$.post('/api/messages/get', function(data) {
for (var i = 0; i < data.length; i++) {
$.jGrowl(data[i].Body.toString().substring(0, 150), { header: 'New Message', sticky: true, });
markDisplayed(data[i].Id);
}
setTimeout(MessagesAjax, 5000);
});
})();
function markDisplayed(id) {
setTimeout(5000); //want it to pause here
$.post("/api/messages/markdisplayed" + id);
console.log("Marking displayed");
}
I just need it to pause so there is a delay before the post is sent back to the server
I'm almost sure that setTimeout is not what I want, but I'm not sure what else to use

Change markDisplayed to:
function markDisplayed(id) {
setTimeout(function() {
$.post("/api/messages/markdisplayed" + id);
console.log("Marking displayed");
}, 5000);
}​
This will cause the function to wait for five seconds before executing the content within it.

replacing
function markDisplayed(id) {
setTimeout(5000); //want it to pause here
$.post("/api/messages/markdisplayed" + id);
console.log("Marking displayed");
}
with
function markDisplayed(id) {
setTimeout(function(){
$.post("/api/messages/markdisplayed" + id);
console.log("Marking displayed");
},5000); //want it to pause here
}
may work for you.

Related

Refresh div only with server time rather than JS

I'm not sure if this is possible or not, but I am able to somehow have my div refresh in server seconds rather a jquery timer?
Or possibly to not have the timer start until all images have loaded?
This method works however it goes out of sync quite often, possibly because of some images still trying to load.
This code was sourced online
Markup:
refreshing in <div id="countDown"></div>
Refresh div after 10 seconds:
$(document).ready( function(){
$(' #avatars').load(' #avatars');
refresh();
});
function refresh()
{
setTimeout( function() {
$(' #avatars').load(' #avatars');
refresh();
}, 10000);
}
Jquery 15sec timer, resets back to 15 after 0
window.onload = function() {
startCountDown(10, 1000, myFunction);
}
function startCountDown(i, p, f) {
var pause = p;
var fn = f;
var countDownObj = document.getElementById("countDown");
countDownObj.count = function(i) {
// write out count
countDownObj.innerHTML = i;
if (i == 0) {
// execute function
fn();
startCountDown(10, 1000, myFunction);
// stop
return;
}
setTimeout(function() {
// repeat
countDownObj.count(i - 1);
}, pause);
}
// set it going
countDownObj.count(i);
}
function myFunction(){};
If you just want to delay the timer until your image loads couldn't you use the callback function on $('#avatars').load('#avatars'); to start the timer?
function refresh(){
$('#avatars').load('#avatars', function(){
setTimeout(function(){
refresh();
}, 10000);
startCountDown(10, 1000, myFunction);
});
}
I believe that this wouldn't start the count down until the images finish loading.
Call refresh function when load status is success.See for more in here http://api.jquery.com/load/
$("#avatars").load(url, function(responseTxt, statusTxt, xhr) {
// debugger;
if (statusTxt == "success")
{
refresh();
}
if (statusTxt == "error")
{
console.log("Error: " + xhr.status + ": " + xhr.statusText);
}
});

setInterval() acts weird after switching tabs

I have created an effect using javascript to show top categories in my project.
As you can see in the image above, it works perfectly fine. But after running for sometime; If the user leaves this page and switched to another tab and come back to this after sometime, then it starts to act weird.
Below is the code which I'm using to make this effect.
var curCat = 0;
var cats = [
"<a href='/search/?cat=1'>Animals</a>",
"<a href='/search/?cat=2'>Graffiti</a>",
"<a href='/search/?cat=3'>Figures</a>",
"<a href='/search/?cat=6'>Landscape</a>",
"<a href='/search/?cat=7'>Portrait</a>",
"<a href='/search/?cat=9'>Other</a>"
];
function catSlider() {
$(catDisplay).html(cats[curCat]);
$(catDisplay).fadeIn();
setInterval(function() {
$(catDisplay).fadeOut();
setTimeout(function() {
if (++curCat >= cats.length) {
curCat = 0;
}
$(catDisplay).html(cats[curCat]);
$(catDisplay).fadeIn();
}, 400);
}, 3000);
}
$(document).ready(function() {
catSlider();
});
What is causing this problem? What am I missing?
Timers get throttled back when the tab doesn't have focus (and many other odd games, such as being accelerated when focus returns), so your setInterval and your setTimeout may get out of sync.
Instead, just use setTimeout, where each action (fade out and fade in) triggers the next:
function catSlider() {
$(catDisplay).html(cats[curCat]);
$(catDisplay).fadeIn();
function fadeOut() {
$(catDisplay).fadeOut();
setTimeout(fadeIn, 400);
}
function fadeIn() {
if (++curCat >= cats.length) {
curCat = 0;
}
$(catDisplay).html(cats[curCat]);
$(catDisplay).fadeIn();
setTimeout(fadeOut, 3000);
}
setTimeout(fadeOut, 3000);
}
And/or you might consider the callbacks that fadeOut and fadeIn can trigger, in particular on the fadeOut:
function catSlider() {
$(catDisplay).html(cats[curCat]);
$(catDisplay).fadeIn();
function fadeOut() {
$(catDisplay).fadeOut(fadeIn); // ***
}
function fadeIn() {
if (++curCat >= cats.length) {
curCat = 0;
}
$(catDisplay).html(cats[curCat]);
$(catDisplay).fadeIn();
setTimeout(fadeOut, 3000);
}
setTimeout(fadeOut, 3000);
}
Side note: If you like, you can replace
if (++curCat >= cats.length) {
curCat = 0;
}
with
curCat = (curCat + 1) % cats.length;
The 3000ms interval might run faster than a 400ms timeout as the browser tries to get the interval in sync after you get back to the tab. To resolve this, you could use a delayed loop, e.g.:
const timer = ms => new Promise(res => setTimeout(res, ms));
(async function() {
while(true) {
hideCurrent();
await timer(400);
showNext();
await timer(2600);
}
})()

Change background images using setTimeout

I have 31 images and I want to display them one after another as the background of a div. I only want it to change when the user hovers over the div. My problem right now is that it just flips through all the images really fast. I am attempting to use setTimeout, but it isn't working. How can I make the delay work?
The name of the div is About_Me_Block and the images are called frame1.gif,frame2.gif ...etc
Here is my code:
function changeImg(counter) {
$('#About_Me_Block').attr("style", "background-image: url(playGif/frame" + counter + ".gif);");
}
$(document).ready(function() {
var hoverAnimate = []
"use strict";
$('#About_Me_Block').mouseenter(function() {
hoverAnimate[0] = true;
var counter = 0;
while (hoverAnimate[0]) {
console.log(counter);
setTimeout(changeImg(counter), 1000);
counter++;
if (counter === 32)
hoverAnimate[0] = false;
}
});
$('#About_Me_Block').mouseleave(function() {
hoverAnimate[0] = false;
$(this).attr("style", "background-image: url(play.jpeg);");
});
});
setTimeout doesn't wait for the function to end, it works lile threading in other languages.
To achieve a what you want, you need to call setTimeout from the changeImg function.
var counter = 0;
$(document).ready(function() {
var hoverAnimate = []
"use strict";
$('#About_Me_Block').mouseenter(function() {
hoverAnimate[0] = true;
counter = 0;
changeImg();
});
$('#About_Me_Block').mouseleave(function() {
hoverAnimate[0] = false;
$(this).attr("style", "background-image: url(play.jpeg);");
});
});
function changeImg() {
$('#About_Me_Block').attr("style", "background-image: url(playGif/frame" + counter + ".gif);");
counter++;
if (counter < 32 && hoverAnimate[0]) {
setTimeout(changeImg, 1000);
} else {
hoverAnimate[0] = false;
}
}
the reason they happen all at once is because while statement doesn't have delay, so all setTimeout will be set up at the same time, thus, calling changeImg all at once.
To solve this problem, you can replace setTimeout with setInterval. Instead of using while, you can just call setInterval like
var counter = 0;
var myTimer = setInterval(changeImg, 1000);
and update counter inside changeImg every time it gets called. After looping, don't forget to
clearInterval(myTimer)
It seems you need to read up on how setTimeout works. It essentially places a reminder to run a function after a given amount of milliseconds have passed. So, when you do setTimeout(changImg(counter), 1000) you are calling changImg(counter) which returns undefined. Therein producing this setTimeout(undefined, 1000) which is why it flips really fast.
So, you can use bind to allow the function to be called later with that parameter built in. Also, make sure you remove the reminders once done with clearTimeout.
function changeImg(counter) {
$('#About_Me_Block').attr("style", "background-image: url(playGif/frame" + counter + ".gif);");
}
$(document).ready(function() {
var hoverAnimate = false, id;
function loop(counter) {
if(hoverAnimate || counter < 32) {
changeImg(counter);
id = setTimeout(loop.bind(this, counter++), 1000);
}
}
$('#About_Me_Block').mouseenter(function() {
hoverAnimate = true;
id = setTimeout(loop.bind(this, 0), 1000);
});
$('#About_Me_Block').mouseleave(function() {
hoverAnimate = false;
// Don't want a reminder for a random counter to wake up.
clearTimeout(id);
$(this).attr("style", "background-image: url(play.jpeg);");
});
});
Two methods for timers - setTimeout and SetInterval (single / repeating)
// setInterval is also in milliseconds
var intervalHandle = setInterval(<yourFuncToChangeImage>,5000);
//this handle loop and make example loop stop
yourelement.yourEvent = function() {
clearInterval(intervalHandle);
};

ellipses word loading screen

What I am trying to do is make a loading screen that shows some message, and a flashing ellipses. It would look like this, but more animated:
Crunching data.
Crunching data..
Crunching data...
Crunching data.
Crunching data..
currently, I have the following code, but it crashes the site, so I'd say it's fair to assume it doesn't work:
function loader(div) {
div.append('<div id="loader"></div>');
load = div.find('#loader');
load.html('Crunching Some Data.');
numberOfPeriods = 1;
while($('#loader').length > 0) {
setTimeout(function() {
if(numberOfPeriods < 4) {
numberOfPeriods++;
for(var i=0; i<numberOfPeriods; i++) {
load.append('.');
}
} else {
load.html('Crunching Some Data.');
numberOfPeriods = 1;
}
}, 200);
}
}
how would one go about doing this?
Try something like this
function showLoader() {
var load;
load = $('<div id="loader"></div>');
$(document.body).append(load);
load.html('Crunching Some Data.');
numberOfPeriods = 1;
interval = setInterval(function(){
if(numberOfPeriods < 4)
{
load.html(load.html() + '.');
numberOfPeriods++;
}
else
{
load.html('Crunching Some Data.');
numberOfPeriods = 1;
}
}, 200);
}
function hideLoader(){
clearInterval(interval);
$('#loader').remove();
}
Don't put setTimeout inside a loop. Instead, test for the "done" condition at the top of the function called by setTimeout (test the length of #loader). If not done, use setTimeout again. If done, call a function which moves things along.

Anonymous function in setTimeout not working

I'm trying to create a delay between two loops of the nivo-slider.
Without the setTimeout everything works just fine (but without delay). So the folloing example works:
$('#slider').nivoSlider({
lastSlide: function(){
$('#slider').data('nivo:vars').stop = true;
// setTimeout(function() {
$('#slider').data('nivo:vars').stop = false;
// }, 2000);
},
});
If I uncomment the setTimeout-lines the slider stops but does not start again? Any ideas why?
Update:
http://jsfiddle.net/kgYNX/
2nd update:
Tried it with a wrapping function, too. The function gets called but if I use setTimeout in the new function it stops working: http://jsfiddle.net/kgYNX/1/
Solved it slightly different:
beforeChange: function(){
$('#slider').data('nivo:vars').stop = true;
var delay = 0;
if ($('#slider').data('nivo:vars').currentSlide == $('#slider').data('nivo:vars').totalSlides - 2) {
delay = 2000;
}
setTimeout(function() {
$('#slider').data('nivo:vars').stop = false;
}, delay);
}
I don't know why "totalSlides - 2", but it works: http://jsfiddle.net/kgYNX/15/
As a variant, you may add custom option to slider vars collection to prevent stop execution on lastSlide handler when slider re-enabled by timeout:
lastSlide: function () {
var dontStop = $('#slider').data('nivo:vars').dontStopOnLast;
if (!dontStop) {
$('#slider').data("nivoslider").stop();
setTimeout(function () {
$('#slider').data("nivoslider").start();
}, 2000);
}
$('#slider').data('nivo:vars').dontStopOnLast = !dontStop;
}

Categories