I've the following JavaScript snippet:
$("#dashboard").addClass("standby").delay(3000).removeClass("standby");
$(".active").removeClass("active");
$("." + target).addClass("active");
$(".showDiv").removeClass("showDiv").addClass("hide");
$("#" + target).removeClass("hide").addClass("showDiv");
While #dashboard is in standby, it should handle all this CSS-Class changes. After this changes, it should display the #dashboard again. So I set delay() between the add and remove of the standby-class. To see if it works I added the too long duration of 3sek.
But it doesn't delay! Why it don't? I don't see it...
delay will only work on actions that go through the animation pipeline, and won't have an influence on the timing of instant atomic operations like that. In order to delay things such as adding or removing classes, then you can use setTimeout.
the .delay() method allows us to delay the execution of functions that follow it in the queue. It can be used with the standard effects queue or with a custom queue.
The .delay() method is best for delaying between queued jQuery effects. Because it is limited—it doesn't, for example, offer a way to cancel the delay—.delay() is not a replacement for JavaScript's native setTimeout function, which may be more appropriate for certain use cases.
.delay() will only delay animations in jQuery.
To set an actual delay, you might want to use setTimeout().
let cancelId;
// ...
cancelId = window.setTimeout(function() {
// ... do stuff ...
}, 3000);
// If you want to cancel prematurely, use `window.clearTimeout`
if (cancelId) {
window.clearTimeout(cancelId);
}
This will execute the code in ... do stuff ... in 3 seconds (3000 miliseconds)
As stated ... delay won't work the way you expect ...
Here is how it works:
$(document).ready(function(){
var audio = new Audio('sang3.mp3');
audio.play();
$("#image1")
.hide()
.attr("src", "https://placeholdit.imgix.net/~text?txtsize=63&bg=FF6347&txtclr=ffffff&txt=Image-1&w=350&h=250")
.fadeIn(1000)
.delay(3000)
.fadeOut(1000)
.queue(function(next) {
$(this).attr("src", "https://placeholdit.imgix.net/~text?txtsize=63&bg=FF6347&txtclr=ffffff&txt=Image-2&w=350&h=250")
next();
})
.fadeIn(1000);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<img src="" id="image1">
Delay won't work the way you expect it to on these line:
$("#image1").delay(9000).attr("src", "image/image1.jpg");
$("#image1").delay(9000).attr("src", "image/image2.jpg");
It will run the attribute change immediately. Why? Because the attribute change isn't part of the "animation". Delay can only be used with with animating functions.
If you only need two images, it might be easiest for you to have two images stacked together, and fade them in and out as needed.
If you want to expand this to many images, try using the more robust ".animate" function to fade in and out. "Animate" can be given a callback function that will be called when complete.
Try utilizing .queue()
$("#image1").delay(5000).fadeIn(3000, function() {
$(this).delay(9000, "task" ).queue("task", function() {
$(this).attr("src", "image/image1.jpg")
.delay(5000).fadeOut(3000, function() {
$(this).delay(9000, "task")
.queue("task", function() {
$(this).attr("src", "image/image2.jpg")
.delay(5000).fadeIn(3000, function() {
$(this).delay(5000).fadeOut(3000)
})
}).dequeue("task")
});
}).dequeue("task")
});
All your delays start on $(document).ready();
$("#image1").delay(5000).fadeIn(3000);
$("#image1").delay(9000).attr("src", "image/image1.jpg");
$("#image1").delay(5000).fadeOut(3000);
$("#image1").delay(9000).attr("src", "image/image2.jpg");
$("#image1").delay(5000).fadeIn(3000);
$("#image1").delay(5000).fadeOut(3000);
Think of it this way. When doc is ready, JS start executing whatever is inside that function, first delay it executes is this: $("#image1").delay(5000).fadeIn(3000);
That will START a delay of 5000 ms and then a fadeOut() with a duration of 3000 ms. That fadeOut is synchronus to the delay, but the next line of code is completely asynchronous to this one.
Then it procceeds to the next line. And so on. It won't wait to your delay to finish, it simply starts counting on the background.
.delay() DOES stack when applied to the same element: JSFiddle
I leave this just in case someone is confused as I was
Seems like for what you are trying to do, you might want to take a look at CSS transitions:
http://css-tricks.com/almanac/properties/t/transition/
You can still have .addClass(), except now your class will utilize these transition properties, and you won't need .delay().
Usually we need to do things before removing the standby state, so we remove the class in an ajax callback :
$("#dashboard").addClass("standby");
$.get('urltoget',function(data){
if(data)
$("#dashboard").removeClass("standby");
else
$("#dashboard").removeClass("standby").addClass('error');
})
Related
I want to replay my jquery function ChangeStats() every 5 seconds, it's currently doing sod all.
function ChangeStats() {
$('body').find('.admin-stats-big-figures-hidden').fadeIn(500);
setTimeout(function() {
$('body').find('.admin-stats-big-figures').fadeOut(500);
}, 500);
}
$(document).ready(function(){
setInterval(ChangeStats, 5000);
})();
Yes I have got the right class names.
No I haven't used underscores in my HTML.
I think it's something to do with my use of "find()", once the DOM has loaded and the function is set is it meant to traverse up the DOM tree instead of down?
EDIT:
Updated code, still not working.
HTML:
<span class="admin-stats-big-figures">%productCount%</span>
<span class="admin-stats-big-figures-hidden">hey</span>
Ok, I am going to go out on a limb and make several assumptions here; one is that you wish to cycle between two elements repeatedly, another is that you are using $(this) in the context of the window rather than a containing element. If either of these are incorrect then the following solution may not be suitable. However, let's give this a shot, eh?
1) You need to use setInterval rather than setTimeout to create a repeating call. You can of course "chain" your timeouts (ie: call the succeeding timeout from the code of the current timeout). This has some benefits in certain situations, but for now let's just assume you will use intervals rather than timeouts.
2) You call the find() jQuery method every time, which is a little unnecessary, especially if you will be repeating the actions so one idea would be to cache the lookup. If you are going to do that a custom object would be more suitable than separate global variables.
3) Some flexibility in terms of starting and stopping the animation could be provided. If we use a custom object as mentioned in (2) then that can easily be added.
4) You are using fadeIn and fadeOut, however if you wish the items to cycle then fadeToggle may be your best solution as it will simply allow you to do exactly that, toggle, without needing to check the current opacity state of the element.
5) Finally in my example I have provided a little extra "padding HTML" in order for the example to look good when run. Fading in jQuery will actually set the faded item to a CSS display of "none" which results in the content "jumping about" in this demo, so I have used some div's and a couple of HTML entity spaces to keep the formatting.
Ok, after all that here is the code..
// your custom animation object
var myAnim = {
// these will be cached variables used in the animation
elements : null,
interval : null,
// default values for fading and anim delays are set to allow them to be optional
delay : { fade: 500, anim: 200 },
// call the init() function in order to set the variables and trigger the animation
init : function(classNameOne, classNameTwo, fadeDelay, animDelay) {
this.elements = [$("."+classNameOne),$("."+classNameTwo)];
// if no fade and animation delays are provided (or if they are 0) the default ones are used
if (animDelay) this.delay.anim = animDelay;
if (fadeDelay) this.delay.fade= fadeDelay;
this.elements[0].fadeOut(function(){myAnim.start()});
},
// this is where the actual toggling happens, it uses the fadeToggle callback function to fade in/out one element once the previous fade has completed
update : function() {
this.elements[0].fadeToggle(this.delay.anim,function(el,delay){el.fadeToggle(delay)}(this.elements[1],this.delay.anim));
},
// the start() method allows you to (re)start the animation
start : function() {
if (this.interval) return; // do nothing if the animation is currently running
this.interval = setInterval(function(){myAnim.update()},this.delay.fade);
},
// and as you would expect the stop() stops it.
stop : function () {
if (!this.interval) return; // do nothing if the animation had already stopped
clearInterval(this.interval);
this.interval = null;
}
}
// this is the jQuery hook in order to run the animation the moment the document is ready
$(document).ready(
function(){
// the first two parameters are the two classnames of the elements
// the last two parameters are the delay between the animation repeating and the time taken for each animation (fade) to happen. The first one should always be bigger
myAnim.init("admin-stats-big-figures","admin-stats-big-figures-hidden",500,200);
}
);
OK, so now we need the HTML to compliment this (as I say I have added a little formatting):
<div><span class="admin-stats-big-figures">One</span> </div>
<div><span class="admin-stats-big-figures-hidden">Two</span> </div>
<hr/>
<input type="button" value="Start" onclick="myAnim.start()"/> | <input type="button" value="Stop" onclick="myAnim.stop()"/>
I have also provided buttons to stop/start the animation. You can see a working example at this JSFiddle - although the stop/start buttons are not working (presumably something specific to JSFiddle) they do work when in context though.
Here im gonna just replace your $(this). and maybe it'll work then.. also using callback.
function ChangeStats() {
$('body').find('.admin-stats-big-figures-hidden').fadeIn(500, function() {
$('body').find('.admin-stats-big-figures').fadeOut(500);
});
}
$(document).ready(function(){
setTimeout('ChangeStats()', 5000);
});
How do I show div.Bravo straight after div.alpha has finished it's .delay(1000)?
I've tried the following, and found that .bravo occasionally appears when .alpha is still shown. I assume an if statement should be used here, but I haven't been able to conjure anything that works.
$(".alpha").delay(1000).hide(0);
$(".bravo").delay(1000).show(0);
Any ideas?
Only use one delay, and switch the elements at the same time:
$(".alpha").delay(1000).hide(0, function(){
$(".bravo").show(0);
});
Or use a timeout instead of delay:
window.setTimeout(function(){
$(".alpha").hide(0);
$(".bravo").show(0);
}, 1000);
you can put it in the callback function:
$(".alpha").delay(1000).hide(0, function() {
//whatever you put here will happen after .alpha finishes hiding
$(".bravo").delay(1000).show(0);
})
Am I able to, and if so how, delay the return of a Javascript function?
For example, say I use JS to set the background of an element that employs CSS3's transitions, and that transition takes 1 second, I'd like to return the function after the transition has finished (after 1 second).
Something like this (pseudo code):
function
element.style = 'background: #aaa; transition: all 1s ease-in;' // this will take 1 second to transition, although the JS is executed immediately
after 1 second // delay the return until the CSS3 transition completes.
return element
I hope this all makes sense! Thank you in advance, your help is much appreciated!
It might be helpful for everyone to see the actual code too: http://jsfiddle.net/BtNSs/1/
No, you're not able to do this. In browsers, JavaScript and the UI share the same thread, so the animation will not begin until your JavaScript code finishes executing.
If you want to do something after the animation completes, use the transitionend event.
How about supplying a callback to the function, and executing that callback after the required amount of time.
function doSomething(callback){
// execute your transition
setTimeout(callback,1000);
}
Live example: http://jsfiddle.net/eAMXK/ - you'll see it output the current time to the console, then a second later do the same.
You do not want to delay the return. You want to execute a callback after one second.
function (element) {
element.style = 'background: #aaa; transition: all 1s ease-in;'
setTimeout(function () {
// whatever you wanted to do with the element;
}, 1000);
}
Ideally, as #AndyE points out, you don't do it "after one second", but when the transitionend event occurs. This is more flexible and generally the right thing to do. Cross-browser support for that event is not yet soild, though. Depending on what you want to achieve, "after one second" might be a lot easier to implement.
I'm trying to make simple slider by using setinterval and jquery.
you can have a look here http://jsfiddle.net/5m2Dq/
Slider works fine when it is in focus on browser but when we go to different tab for more than 5 min all the div's come's under each other, and start toggling.
$('#fbLoginSlide div:gt(0)').hide();
setInterval(function(){
$('#fbLoginSlide :eq(0)').fadeOut('slow').hide()
.next('div.loginSlide').fadeIn('slow')
.end().appendTo('#fbLoginSlide');
},2000);
Is there a simple way to achieve the sliding effect like this without any plugin.
This occurs probably because your browser starts missing timeouts. Especially if you are viewing another tab, the browser thinks that it is not important to call the callback with exactly 2 second intervals. You should ditch the setInterval function altogether! Use instead the completion callback of fadeOut and fadeIn to trigger the effects.
Try something like
var cycle = function() {
$('#fbLoginSlide :eq(0)').fadeOut('slow').hide()
.next('div.loginSlide').fadeIn('slow', function() { setTimeout(cycle, 1500); })
.end().appendTo('#fbLoginSlide');
};
cycle();
I'm required to develop a slideshow (not an existing one) with jQuery. I was able to change picture with a function that I created named changePic (takes an image link). It incorporates the fading animation from the jQuery library.
For the slideshow I'm trying to use a while loop. It kind of works, except that it doesn't wait for the animation to finish.
How do I, a) wait for the animation to finish, b) delay the changing picture so it display the picture for a couple of seconds?
Also tried Settimeout, and it doesn't work.
Edit:
Basically changing image is like this:
function changePic(imglink){
var imgnode = document.getElementById("galleryimg");
$(imgnode).fadeTo(500, 0, function(){
$(imgnode).attr("src", imglink);
$(imgnode).fadeTo(1000, 1);
})
}
and the slideshow code is like this, but obviously it shouldn't.
function slideshow(gallerylinks){
var i=0;
while (i<gallerylinks.length){
changePic(gallerylinks[i]);
i++;
}
}
You could always try ditching the while loop, and going with a perpetually recursive function...
on the .animate, you could add a timeout function (at whatever interval) that calls the changePic function. As I have no idea what your code looks like, I will provide a fantastically generic outline.
/* array of imgUrls */
var imgUrls = new Array(); //populate it however
changePic(slideToShowIndex, fadeOutSpeed, fadeInSpeed, slideDelay)
{
$('#slideHolder').animate({ opacity: 0}, fadeOutSpeed , function(){
$('#slideHolder').attr('src', imgUrls[slideToShowIndex]);
$('#slideHolder').animate({ opacity: 1 }, fadeInSpeed, function() {
setTimeout(function() { changePic(slideToShowIndex+1, fadeOutSpeed, fadeInSpeed, slideDelay);}, slideDelay});
});
}});
}
$(document).ready(function() {
changePic(0, 5000, 5000, 10000);
});
This should (in theory) fade the image out, swap it with the new one, and fade it in (both taking 5 seconds) and then adding a delay to call itself with the next slide index in 10 seconds.
This is in no way perfect, but does outline the general idea. Since we have no idea what your code looks like, I can only assume your setTimeout was in the wrong spot. Doing it like this will make sure that the animation has finished before the timeout is set. This guarantees that the slide wont change until after the animation has changed.
of course you could always use a combination of the ':not(:animated)' selector and a setInterval to achieve much the same effect.
EDIT: made a slight change to stack the animations properly. The thoery behind this still works even with the OPs addition of code.
You could have provided more details or example code but have a look at stop() and delay() functions.