End a script 1 second after the first scripts finishes - javascript

I want to run an animation function after another function (handleScreen) has completed. The animation function will fade out parts of the page after 1 sec. I tried adding a .promise function but that doesn't seem to work.
https://jsfiddle.net/Dar_T/eqdk82ru/1/
handleScreen(mql).promise().done(function() {
setTimeout(function() {
$("#name,#splash").fadeOut("slow");
}, 1000);
});

You can use jquery Deferred object to resolve this:
handleScreen creates a $.Deferred that will be passed to the animation function. A promise from this deferred is then returned.
function handleScreen(mql) {
var def = $.Deferred();
mql.matches ? smallBlock(def) : largeBlock(def);
return def.promise();
}
The animation function marks the deferred as resolved once the animation finishes (using TweenLite onComplete argument on the last animation):
function largeBlock(def) {
setTimeout(function () {
TweenLite.defaultEase = Linear.easeNone;
TweenLite.set('.square', { visibility: 'visible' });
var tl = new TimelineLite();
tl.fromTo('.l1', 2, { height: 0 }, { height: 227 });
tl.fromTo('.l2', 3, { width: 0, }, { width: 445 });
tl.fromTo('.l3', 2, { height: 0 }, { height: 227 });
tl.fromTo('.l4', 3, { width: 0 }, { width: 445, onComplete: def.resolve });
tl.timeScale(4);
}, 600);
}
fadeOut is executed once the deferred is done:
handleScreen(mql).done(function() {
setTimeout(function() {
$("#name,#splash").fadeOut("slow");
}, 1000);
});
});
Demo: https://jsfiddle.net/g5f7pex3/1/

A simple approach that addresses the problem in a different way than you were thinking:
var alreadyFaded = false;
function FadeSplash()
{
if(alreadyFaded == false){
//prevent this from running a second time
alreadyFaded = true;
$("#name,#splash").fadeOut("slow");
}
}
$(function () {
//do something
//make the fade happen upon finishing if it hasn't already
FadeSplash();
});
$(function () {
//by default, the fade will happen after 5 seconds if FadeSplash()
//wasn't already called by the above function.
$("#splash,#name").show(), setTimeout(function () {
FadeSplash();
}, 5000)
});
Here's a working JSFiddle to demonstrate:
https://jsfiddle.net/tthhaft1/

Short answer: you can't do it naturally. Long Answer: use an interval to check for a flag, also, there is no need for 2 document ready:
$(document).ready(function () {
var finished = false;
SOME FUNCTION
//Inside SOME FUNCTION do your stuff, and before returning or whatever it is doing:
var intervalCheck = setInterval(function () {
if (finished) {
//Do your stuff you need to do after those 5 secs.
clearInterval(intervalCheck);
}
}, 1000);
$("#splash,#name").show(), setTimeout(function () {
$("#name,#splash").fadeOut("slow")
finished = true;
}, 5000);
});

Related

Run a certain script JS after x seconds that the page is loaded

I have this script:
<script>
var Webflow = Webflow || [];
Webflow.push(function() {
MemberStack.onReady.then(function(member) {
if(member.memberPage){
window.location.replace(member.memberPage);
}else{
setTimeout(function() { location.reload(true); }, 3000);
}
})
});
</script>
I would like this script to run after 5 seconds after the page loads, how could it be solved?
How about window.onload along with setTimeout ?
Example:
window.onload = function() {
setTimeout(function () {
// Do stuff here
}, 5000);
}
or, you may also use event listeners
function delayAndExecute() {
setTimeout(function () {
// Do stuff here
}, 5000);
}
// Everything but IE
window.addEventListener("load", function() {
delayAndExecute();
}, false);
// IE
window.attachEvent("onload", function() {
delayAndExecute();
});
<script>
var Webflow = Webflow || [];
window.onload = function () {
setTimeout(function () {
Webflow.push(function () {
MemberStack.onReady.then(function (member) {
if (member.memberPage) {
window.location.replace(member.memberPage);
} else {
setTimeout(function () { location.reload(true); }, 10);
}
})
});
}, 5000);
}
</script>
So i I tried to do this but the script repeats itself every 5 seconds without taking setTimeout (function () {location.reload (true);}, 10)into consideration; I would like the script to start only the first time in 5 seconds later loading the script
5 seconds after window.onload you are pushing a function into the webflow Array.
But you are never calling it. Add webflow[0](); to your code;
var Webflow = Webflow || [];
window.onload = function () {
setTimeout(function () {
Webflow.push(function () {
MemberStack.onReady.then(function (member) {
if (member.memberPage) {
window.location.replace(member.memberPage);
} else {
setTimeout(function () { location.reload(true); }, 10);
}
})
});
webflow[0]();
}, 5000);
}

Jquery functions Delay shortens with each Interval

I am not sure how to ask this question. I made a jQuery function for a banner.
$(document).ready(function() {
ionanim();
setInterval(ionanim, 12000);
function ionanim() {
$(function () {
$('.ion1anim').fadeIn(500, function () {
$(this).delay(5000).fadeOut(500);
});
});
$(function () {
$('.ion2anim').delay(6000).fadeIn(500, function () {
$(this).delay(5000).fadeOut(500);
});
});
};
});
Link for the full animation : http://jsfiddle.net/L8XHL/11/
But with each intervatl on the setInverval the animations go close to each other after some time they overlap each other.
Did i do anything wrong?
Intervals and animations aren't exact enough to handle the timing that you require. I'd suggest using a self-executing function instead so that it will never overlap.
Also, you are over-using the document ready handler. Please stop.
http://jsfiddle.net/L8XHL/13/
$(document).ready(function () {
ionanim();
function ionanim() {
$('.ion1anim').fadeIn(500, function () {
$(this).delay(5000).fadeOut(500, function () {
$('.ion2anim').fadeIn(500, function () {
$(this).delay(5000).fadeOut(500,ionanim);
});
});
});
}
});
I would further modify this to work more like a slider so that you can add an infinite number of items without having a huge pyramid of code.
http://jsfiddle.net/L8XHL/17/
$(document).ready(function () {
$(".ionbanner .bottom div").first().siblings().hide();
anim();
function anim() {
var curr = $(".ionbanner .bottom :visible");
var next = curr.next();
if (next.length == 0) {
next = curr.siblings().first();
}
curr.delay(5000).fadeOut(500,function(){
next.fadeIn(500,anim);
});
}
});
Or you could try something like this: http://jsfiddle.net/L8XHL/16/
$(document).ready(function() {
var anim1 = function() {
$('.ion1anim').fadeIn(1000, anim1Callback);
},
anim1Callback = function() {
$('.ion1anim').fadeOut(1000, anim2);
},
anim2 = function() {
$('.ion2anim').fadeIn(1000, anim2Callback);
},
anim2Callback = function() {
$('.ion2anim').fadeOut(1000, anim1);
};
anim1();
});

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;
}

setInterval and setTimeout speed changes

My problem is within some JavaScript:
var mijnfunctie = function(){
//balk 1 2 3
setTimeout(function(){
$("#balk1").animate({"margin-left": "0px"}, 400);
$("#balk2").animate({"margin-left": "0px"}, 400);
$("#balk3").animate({"margin-left": "0px"}, 400);
});
setTimeout(function(){
$("#balk1").animate({"margin-left": "-2000px"}, 400);
$("#balk2").animate({"margin-left": "4000px"}, 400);
$("#balk3").animate({"margin-left": "-5000px"}, 400);
}, 2000);
//balk 4 5 6
setTimeout(function(){
$("#balk4").animate({"margin-left": "0"}, 400);
$("#balk5").animate({"margin-left": "0"}, 400);
$("#balk6").animate({"margin-left": "0"}, 400);
}, 3000);
setTimeout(function(){
$("#balk4").animate({"margin-left": "2000px"}, 400);
$("#balk5").animate({"margin-left": "-4000px"}, 400);
$("#balk6").animate({"margin-left": "5000px"}, 400);
}, 5000);
setInterval(mijnfunctie, 6000);
};
mijnfunctie();
this is made for a slider and it works fine. For six times, and after the sixth it's starting to mix up. So somewhere the time isn't right, but where?
setInterval will enqueue a repeated function. Since you're doing it at the end of the function you're enqueuing, after twelve seconds, it will run twice. After each six more seconds, the count of them will double. Slowly, this will bring the browser to its knees. You'll have 500 timers set up in mere one minute, 500 000 timers the second minute...
Either move setInterval outside of the function you want to repeat, or (better) change it to setTimeout(which will enqueue just one occurence of the call).
function mijnfunctie(){
...
setTimeout(mijnfunctie, 6000);
}
Secondly, your first call to setTimeout is missing its argument. No matter what the default value is, you should always specify it.
Third, if any animation delays by a few seconds, then the subsequent animations will run immediately after. To prevent this, you may want to chain the animations instead of relying on correct timing. In that case, to prevent the pyramid effect (extreme indenting), I suggest this form:
function phase1(){
$(...).animate(..., phase2);
}
function phase2(){
...
...
function phaseN(){
$(...).animate(..., phase1);
}
You cannot rely on delay in setTimeout, this value means only minimal delay for the function. Instead you should chain those functions.
var mijnfunctie = function(){
setTimeout(function(){
$("#balk1").animate({"margin-left": "0px"}, 400);
$("#balk2").animate({"margin-left": "0px"}, 400);
$("#balk3").animate({"margin-left": "0px"}, 400, function () {
setTimeout(function () {
$("#balk1").animate({"margin-left": "-2000px"}, 400);
$("#balk2").animate({"margin-left": "4000px"}, 400);
$("#balk3").animate({"margin-left": "-5000px"}, 400, function () {
setTimeout(function () {
$("#balk4").animate({"margin-left": "0"}, 400);
$("#balk5").animate({"margin-left": "0"}, 400);
$("#balk6").animate({"margin-left": "0"}, 400, function () {
setTimeout(function () {
$("#balk4").animate({"margin-left": "2000px"}, 400);
$("#balk5").animate({"margin-left": "-4000px"}, 400);
$("#balk6").animate({"margin-left": "5000px"}, 400, function () {
setTimeout(mijnfunctie, 600);
});
}, 1600);
});
}, 600);
});
}, 1600);
});
}, 0);
};
mijnfunctie();
anyway I would rather suggest something like that :)
(function () {
var objects = new Array(6),
index = 0,
steps = [
[[0,'0px'],[1, '0px'],[2, '0px']],
1600,
[[0,'-2000px'],[1,'4000px'],[2,'-5000px']],
600,
[[3,'0px'],[4,'0px'],[5,'0px']],
1600,
[[3,'2000px', '-400px', '5000px']],
600
],
i = 6,
crawler;
while(i--) { objects[i] = $('#balk'+(i + 1)); };
crawler = function () {
var step, k;
if (index >= steps.length) index = 0;
step = steps[index];
++index;
if (typeof(step) == 'number') {
setTimeout(step, crawler);
} else {
k = step.length - 1;
while(k--) {
objects[k[0]].animate({'margin-left': step[k[1]]}, 400, (k ? null : crawler)});
}
}
};
crawler();
}());
or something more generic and reusable
Gerrit you are using setInterval(mijnfunctie, 6000); function inside the same function that's why it is looping itself and calling setInterval(mijnfunctie, 6000); function multiple times..
Therefore calling setInterval(mijnfunctie, 6000); function only once (where first time is called) is adviced.
Enjoy..!

Stop timer on hover

I'm not a JS coder my any means. I know enough to make things do what I want, but couldn't code from scratch. My issue is:
We have a shopping cart that when you add a product the cart shows itself for 4 secs unless the customer hovers over the cart. I can't seem to get it to stop the timeout when the cursor is hovered over it.
$(document).ready(function () {
setTimeout(function () { $('#ctl00_ctl00_ctlHeader_divOrderProducts').hide(); }, 4000);
});
Store the return of setTimeout() in a variable, and use that to clearTimeout():
// t is a global scope variable.
// Probably a good idea to use something better than 't'
var t;
$(document).ready(function () {
// Store the return of setTimeout()
t = setTimeout(function () { $('#ctl00_ctl00_ctlHeader_divOrderProducts').hide(); }, 4000);
});
$('cart-selector').hover(function() {
if (t) {
// Call clearTimeout() on hover()
clearTimeout(t);
}
});
You need to set your timer to a variable:
var timer1 = setTimeout(function () { ... })
then use:
clearTimeout(timer1)
You need to save the return value of setTimeout() so you can later use it with clearTimeout(). One way to that is like this:
$(document).ready(function () {
var hideTimer = setTimeout(function () {
$('#ctl00_ctl00_ctlHeader_divOrderProducts').hide();
}, 4000);
$('#ctl00_ctl00_ctlHeader_divOrderProducts').hover(function() {
if (hideTimer) {
clearTimeout(hideTimer);
hideTimer = null;
}
});
});
If you want to re-enable the timer when the mouse leaves the cart again (assuming #ctl00_ctl00_ctlHeader_divOrderProducts is the cart), you can do so like this:
$(document).ready(function () {
var hideTimer;
function delayHideCart() {
if (!hideTimer) {
hideTimer = setTimeout(function () {
$('#ctl00_ctl00_ctlHeader_divOrderProducts').hide();
}, 4000);
}
}
delayHideCart();
$('#ctl00_ctl00_ctlHeader_divOrderProducts').hover(function() {
if (hideTimer) {
clearTimeout(hideTimer);
hideTimer = null;
}
}, function() {
delayHideCart();
});
});
This should do it:
$(document).ready(function () {
var timeout = setTimeout(function () { $('#ctl00_ctl00_ctlHeader_divOrderProducts').hide(); }, 4000);
$('#ctl00_ctl00_ctlHeader_divOrderProducts').mouseover(function() {
clearTimeout(timeout);
});
});
You save the timeout as a variable and then call clearTimeout when you mouseover the cart and pass in that timeout.
var timer = window.setTimeout(function () {
$('#ctl00_ctl00_ctlHeader_divOrderProducts').hide();
if(someCondition)clearTimeout(timer);
}

Categories