Effect Delay Trick
Here is a quick trick for getting an effect to delay without using setTimeout.
Let's say, for example, that I want to show an alert message on the page every time a user clicks on a certain button. But I don't want it to stay there forever; I want it to go away a few seconds later. You know, like the way they do in all of those crazy Web 2.0 sites.
The HTML
Well, first I'll need a message, along with a container for it:
-
<div class="quick-alert">Alert! Watch me before it's too late!</div>
Oh, I should also put my button into the HTML—something like this: <input type="submit" id="show-alert" value="Show Alert" />
The CSS
Now I could also use some stylin' for that quick-alert class:
-
.quick-alert {
-
width: 50%;
-
margin: 1em 0;
-
padding: .5em;
-
background: #ffa;
-
border: 1px solid #a00;
-
color: #a00;
-
font-weight: bold;
-
display: none;
-
}
I'll stick that in my stylesheet so that it's ready to be applied to our new, button-generated DIV.
Inserting the Content
On to the code! First, we'll get our message to be inserted when someone clicks on the "Show Alert" button. Let's put the message right after the button, like so:
-
$('<div class="quick-alert">Alert! Watch me before it\'s too late!</div>')
-
});
-
});
So, basically, what I'm saying here is, upon clicking the <input id="show-alert" /> button, create this div with the class and all the text inside of it, and place it right after the button. Notice the backslash in "it\'s." That keeps jQuery from getting confused That escapes the single quote, which is necessary because otherwise — as Dave Cardwell explains in his comment — "the JavaScript parser would interpret that as the close of the string."
Adding the Effects
So far, so good. Now I'm going to add my .fadeIn() and .fadeOut() effects. And after those are done, I'll remove the div that I just created. No sense keeping it around:
Because I put $(this).remove() in the callback of the .fadeOut() method, it occurs after the the fading out is finished.
The Delay
So, here's the thing. The entry's title says that this is a trick, right? Well, I hope it's not a dirty trick, but here goes the full code:
Do you see that .animate() method there? I have it animating to a full opacity in 3 seconds. But the div is already at full opacity, so it just sits there looking like it's doing nothing for 3 seconds. Isn't that cute?
Here you go. Try it out for yourself:
I hope you enjoyed the message while it lasted!


January 17th, 2007 at 4:18 am
omg. Thats just what I've been looking for, thank you!
January 17th, 2007 at 4:58 am
now that was cool and simple, thanks!
January 17th, 2007 at 8:04 am
Nice stuff Karl,
As an added bonus, you can click the button several times and see mesages appearing and fading out one after the other !
Neil
January 17th, 2007 at 8:15 am
Karl,
Firefox 1.5.0.7 - brilliant!
Firefox 2.0.01 - brilliant!
IE 7 - brilliant!
Just thought I'd let you know a couple of bugs I noticed:
All on Win XP Pro
IE 6 SP2 - message didn't fade in or out
Firefox 1.0.8 - message flicker at end of fade in and beginning of fade out
Opera 9.10 - slight "shift" in the text upon complete fade in
Netscape 7.2 - message flicker at end of fade in and beginning of fade out
Netscape 8.1.2 - message flicker at end of fade in and beginning of fade out
January 17th, 2007 at 9:46 am
Thanks for the browser testing, Neil! Oddly, I just tried it in IE 6 SP2, and the fades were working properly. I don't have the version of Firefox/Netscape that produced bugs, but I'll take your word for it.
The Opera bug is a little disconcerting. It might have to do with the way jQuery calculates the height of the div before fading it in. I'll have to install Opera on my machine and give it a whirl. Thanks again!
January 17th, 2007 at 10:07 am
The reason you need the backslash is because otherwise the JavaScript parser would interpret that as the close of the string, not for jQuery's sake.
Nice tip and write up - Jonathan Howard's Pause plugin performs a similar function.
January 17th, 2007 at 10:48 am
Thanks, Dave, for the clarification. You're right, of course. It was late, and I was too tired to think about what I was writing at that point. Should have waited for the clear light of dawn, as they say.
Thanks, too, for the link to the pause plugin. Cheers!
January 17th, 2007 at 11:03 am
@Karl:
I would think Dave's recommendation of a pause() plug-in would be a more elegant and efficient method of doing this. The animate() method is going to be wasting some processing--as it will attempt to animate the layer (i.e. the flicker effect.)
At least the pause plug-in does exactly what you want w/no extra overhead.
January 17th, 2007 at 11:22 am
@Dan,
(I've got to stop using these emoticons!) Certainly not a "best practice." A more elegant solution would use
Yep, you're absolutely right. This entry was meant more as a quick (and dirty) trick, emphasis on the trick.
setTimeout, which Jonathan's does, and which I mention in the first paragraph. That said, I checked CPU usage while running this, and the impact — on my machine at least — was negligible. Still, I really appreciate the comment. It never hurts to reinforce these things.January 17th, 2007 at 1:04 pm
Help me understand: On line 4 'this' refers to the button being clicked but on line 8 'this' refers to the div. Why? and when did it change?
January 17th, 2007 at 1:23 pm
Opera 9.10 (Mac) looks fine to me.
January 18th, 2007 at 7:14 pm
Erin,
In line 4, we're inside the event handler for the click event of
#showAlert.thispoints to that element.In line 8, we're inside a function that acts as a callback for the finished effect, so
thisrefers to the element which has been animated.HTH.
January 26th, 2007 at 8:50 am
Uh, that last comment was mine, not Erin's.
January 26th, 2007 at 9:38 am
Fixed!
And thanks, Choan, for explaining
thisto Erin.February 12th, 2007 at 6:12 am
I`ve changed it a bit to make this work with a text-link without getting moved to the top of the page.
It works for me, but being totally new to Jquery I dont know if the code is correct, but hey...it works
I really love your tutorials keep them coming
$(document).ready(function() {
$('#quick-alert').hide();
$('a#show-alert').click(function() {
$('#quick-alert').fadeIn('slow')
.animate({opacity: 1.0}, 6000)
.fadeOut('slow', function() {
$(this).remove();
});
return false;
});
});
February 12th, 2007 at 5:50 pm
Well done, Benjamin. That's exactly what you need to do — add
return falseto the.click()handler.March 26th, 2007 at 2:30 pm
Hi Karl,
Great website - it's been a tremdous help. I would like to incorporate this idea but instead of it being activated by a button I would like it to trigger when the page loads. I.e. when the page loads it displays the message for xx seconds and then the message disappears.
Any ideas?
Many thanks, and keep up the great tutorials!
March 26th, 2007 at 4:28 pm
Hi Neil,
So glad you like the tutorials! For triggering on page load, you might want to just use
window.setTimeout(). Say you want to show<div id="temp">temporary message</div>for 3 seconds when the window loads. You could do something like this:Hope that helps!
March 27th, 2007 at 1:52 am
Hi Karl,
Thanks for the reply - here's what I went with:
var removeTemp = function() { $('#message').fadeOut('slow', function() { $(this).remove(); }); };window.setTimeout(removeTemp,3000);
April 9th, 2007 at 5:27 pm
What about a delay before any effect takes place in order to take advantage of implementing this with other scripts and effects?
April 11th, 2007 at 10:55 pm
Hi John, I'm not sure I'm understanding your question correctly, but I think it's just a matter of where you position the delay in your code, whether it's the "trick" or the setTimeout().
April 19th, 2007 at 12:53 pm
Hello I'm new to the jQuery world and new to JavaScript. I'm looking to use the "Delay Trick" for an in-page massage, but I only want the message to appear on the first click and not reoccur.
Or better yet to display something different on an additional click.
I was wondering if any one out there has tackled this one.
April 27th, 2007 at 6:11 pm
Hi Mike,
If you only want to trigger an event one time, you can take advantage of jQuery's
.one('event', fn)method.If you want to display something different on additional clicks, try something like this:
This creates a
divelement withid="foo"when the DOM is ready, hides it, and inserts it at the beginning of thebody. Then it sets a counter and changes the message based on whether the counter is at 0 or more than 0. As for the rest, well, it's pretty much the same as what I wrote about in the entry.Hope that helps.
May 21st, 2007 at 11:42 am
[...] Otra forma de hacer esto mismo es utilizando el siguiente código (http://www.learningjquery.com/2007/01/effect-delay-trick): [...]
July 11th, 2007 at 3:11 am
Hi Karl,
I'm trying to use your delay trick to reposition a background-image position, delay the animation for a split second, then return the background-image to it's original position -- but getting no love.
$("#flip").css("background-position", "top right")
.animate({opacity:1.0}, 3000)
.css("background-position", "top center");
Is my thinking flawed here?
July 11th, 2007 at 7:35 am
Hi Alex,
The problem is that this trick only works with jQuery's effects (slideUp, fadeIn, etc.), not with your standard css manipulation, because it takes advantage of jQuery's built-in queuing of effects. For delaying something like background position, I'd recommend using a
setTimeout(), as I describe in comment 18 above. Let me know if that works for you.July 11th, 2007 at 9:27 pm
Thanks Karl,
Yes, that's what I thought. Was hoping there might be a more jQuery-like method to pull it off.
Do you imagine CSS manipulations ever being added to jQuery's animation queue (or have their own queue)? The ability to pause between chained CSS instructions would seem to open up a huge potential for animation without adding a massive overhead to the library (I'm guessing there).
September 11th, 2007 at 9:37 pm
Seems like this effect delay trick is not working so well with jquery 1.2
September 11th, 2007 at 11:05 pm
Hi Luis,
I just put up a test page with the script from here, and it seems to be working fine.
Please have a look and see if it causes any problems for you:
effect delay test
Thanks.
September 12th, 2007 at 1:20 am
Weird... It's working fine now.
October 21st, 2007 at 9:06 am
Very nice alert effect !
October 30th, 2007 at 2:42 pm
I've been playing around with it for a bit, but i'm new to javascript and am having no luck. I have a div with a text link in it, when someone clicks it, I want the alert to appear in another div right below that one, and push everything below it down. Right now, the alert appearing on top of the div with the link it it(as in, the alert hovers over the div), just a pixel or two below the link. How would I fix this? Is it possible to place the div somewhere on the page, and have the link that calls the alert somewhere else on the page? it's only appearing right below the link/button. Sorry, again I'm new.
October 30th, 2007 at 5:28 pm
http://www.muttmansion.com/lightbox/fader/
I found this page which displays a similar alert effect, but doesn't remove the div once it's been placed in the page, it just fades the opacity, leaving the space it occupied when visible. It uses ajax though, to fetch a seperate page for the alert box. and no matter where the button is at, in the page, it will always display the alert inside the same box.. whereas yours only displays it directly below the button.(if I did it right)
I'm trying to find/make/get a script that will display the message(grabbed from another file(ajax)) in a div, and no matter where I have the button at, always have the messages displayed inside that div, not directly under the button. I want it to act like yours, in that it removes the space where the div occupied when it was visible, after it disappears.
could you point me in the right direction?
October 31st, 2007 at 3:04 am
That's a great trick and simple!! Thanks.
October 31st, 2007 at 3:07 am
That's great trick and simple !! Thanks.
November 28th, 2007 at 2:35 pm
When I found this article, I was looking for a lightbox script with a fader but I'm glad I came across this because I wasn't familiar with JQuery library. Within 10 minutes of reading this article I was using JQuery library and the example here was a great start for somebody already familiar with JavaScript and coding to show the basic power of this great tool.
Thanks for the article !!
December 18th, 2007 at 8:59 pm
Great, I have adapted to perform some additional tasks :
$('#dirConnect a#noframe').click(function (e) {e.preventDefault();
var answer = $('#url_connex');
if (answer.is(':visible')){
answer.slideUp(400);
//alert("La fenêtre de connexion est fermée");
$('#connect_msg').html("La fenêtre de connexion est fermée").css({ border:"1px solid red" ,color:"red" }).insertAfter( $(this) ).fadeIn('slow').animate({opacity: 1.0}, 3000).fadeOut('slow');
}else{answer.slideDown(400);
//alert("La fenêtre de connexion est ouverte");
$('#connect_msg').html("La fenêtre de connexion est ouverte").css({ border:"1px solid orange" ,color:"orange" }).insertAfter( $(this) ).fadeIn('slow').animate({opacity: 1.0}, 3000).fadeOut('slow');
}
return false;
});
March 7th, 2008 at 11:12 am
exelente plungin, muchas gracias, saludos desde Chile!!
March 19th, 2008 at 7:26 am
Cool Trick
Do you have a tip for me how to modify this a little bit?
I have a dropdown menu. Do open it I have to click a link which I defined:
$("a.btn_options_bar").click(function () {
$("div.menu_options").slideToggle("normal");
$("a.btn_options_bar").toggleClass("btn_options_bar_act");
});
So, clicking on the button slides down the menu and sets the button to active
status. Clicking again sets everything back. The menu consists of an div > .menu_options
within this div there is a list (ul/li).
To close the menu you have to click again. But I also want to hide the menu when I move
out of the ul/li area after 1 sec. Hence I tried something with mouseout but the event starts at
once. Any idea how to realize that kind of functionality?
thanks indeed!
March 19th, 2008 at 2:07 pm
Hi Florian,
To get that to work, you'll need to use a standard JavaScript setTimeout() method. Or, you could take a look at the hoverIntent plugin:
http://cherne.net/brian/resources/jquery.hoverIntent.html
March 24th, 2008 at 9:03 pm
that's great
April 4th, 2008 at 9:27 am
Its perfect and cool... i like it