<!DOCTYPE html>
<title>Delayed Hide Of A Related Element</title>
<style type="text/css">
#footer {
background-color: #F0F0F0 ;
border-top: 1px solid #CCCCCC ;
bottom: 0px ;
display: none ;
left: 0px ;
position: fixed ;
width: 100% ;
#footerInner {
padding: 10px 15px 35px 15px ;
</style>
</head>
Delayed Hide Of A Related Element
<a id="openFooter" href="##">Show Footer</a>
<div id="footer">
<div id="footerInner">
Hello - I am the footer. I might have a lot of
neat things in me to which the the user wants
to gain access.
<!-- Load scripts after our DOM is ready. -->
<script type="text/javascript" src="./jquery-1.4.2.js"></script>
<script type="text/javascript">
// Get references to our key dom elements.
var openFooterLink = $( "#openFooter" );
var footer = $( "#footer" );
// Create a function that sets an inactive timer on the
// footer. This will be called when the footer is opened
// or when the user mouses out of the footer.
function setInactiveTimer(){
// We are goint to store this timer as a property of
// the footer itself.
footer.data(
"inactiveTimer",
setTimeout( closeFooter, (4 * 1000) )
// I remove any inactive timer on the footer.
function clearIntactiveTimer(){
clearTimeout( footer.data( "inactiveTimer" ) );
// I open the footer.
function openFooter(){
// Open the footer.
footer.slideDown( 500 );
// I close the footer.
function closeFooter(){
// Slide the footer up (to close it).
footer.slideUp( 500 );
// -------------------------------------------------- //
// -------------------------------------------------- //
// Hook up the open footer link. When we do this, not only
// do we want to open the footer, we also want to set a timer
// so that the footer will close if it is not being used.
openFooterLink.click(
function( event ){
// Cancel the default event as this is not a true
// link action.
event.preventDefault();
// Check to see if the footer is currently animating.
// If it is, then we don't want to listen to this
// click as it might be a double-click.
if (footer.is( ":animated" )){
return;
// Clearn any existing timer since the user clearly
// want to interact with the footer.
clearIntactiveTimer();
// Call the open footer.
openFooter();
// Set the inactive timer.
setInactiveTimer();
// Attach a mouse enter handler on the footer to hook into
// user interaction. If the user mouses over the footer,
// then we want to remove any timers.
footer.mouseenter(
function(){
// Check to see if the footer is currently
// animating. If it is, then let's ignore since
// we are not wired to stop closing mid-animation.
if (footer.is( ":animated" )){
return;
// First, clear any existing timer that might take
// control of the footer display.
clearIntactiveTimer();
// Attach a mouse exit handler on teh footer to hook into
// user disinterest. If the user mouses out of the footer,
// then we want to start thinking about closing it.
footer.mouseleave(
function(){
// Check to see if the footer is currently
// animating. If it is, then let's ignore since
// we are not wired to stop closing mid-animation.
if (footer.is( ":animated" )){
return;
// Set inactivity timer for future-close.
setInactiveTimer();
</script>
</body>
</html>
In this demo, the user can actively engage in three different interactions:
Open the footer.
Mouse into the footer.
Mouse out of the footer.
When the user clicks the open-footer link, we want to show the footer and configure a timer that will close the footer if the user chooses not to engage with it. We do this through the use of setTimeout(). In the above code, if the user does not engage with the footer within 4,000 milliseconds (4 seconds), our timer will execute the closeFooter() function, sliding the footer down and out of view.
If the user does choose to engage with the footer, however, we want to make sure that the footer does not close while the user is interacting with it. As such, when the user mouses into (mouseenter) the footer, we use clearTimeout() to cancel the future invocation of our closeFooter() callback.
In this particular demo, I am checking the animation status of the footer before I perform any further UI logic. In this approach, we don't have to worry about double-clicking and mid-animation interactions. We can always expand our logic to deal with such situations later; however, that quickly adds complexity that is not relevant for this explanation.
While approaches to this kind of situation may vary widely, I think you'll find that they typically operate off of the setTimeout() and clearTimeout() functions. I hope that this helps shed some light on delayed interface reactions based on user interactions.
Want to use code from this post?
Check out the license.
Enjoyed This Post?
Share the Love With Your Friends!
Tweet This
Great article by @BenNadel - Using SetTimeout() To Delay The Closing Of A Related UI Element Based On User Interactions https://www.bennadel.com/go/2025
Ben, take a look at my jQuery doTimeout plugin, which is very useful for delayed code execution, especially when dealing with polling loops or hover intent:
http://benalman.com/projects/jquery-dotimeout-plugin/
In addition, my jQuery throttle / debounce plugin is geared towards rate-limiting function execution, so you might find that useful when dealing with other events:
http://benalman.com/projects/jquery-throttle-debounce-plugin/
FYI - I've been meaning to mention this for a while, but you should consider increasing the volume on your mic. I always end up having to jack up my volume to hear any of your screencasts. The volume on your screencasts is easily 70%+ quieter than other sources I listen to. I have Winamp at 20% volume and it's still way louder than your screencasts. In order to hear you, I always have to turn off any other audio and jack the volume way up.
@Cowboy,
Very cool plugins - you're like a jQuery plugin wizard. I remember at last year's jQuery conference you told me you had a lot of ideas for plugins... no doubt! I particularly the like throttle() concept.
@Dan,
I agree with you on that 100%. But, I'll be straight-up honest - I have no idea how to do that. Would that be a system setting, or an app setting (JING) do you think?
Also, I seem to remember you also writing some "debouncing" code a good while ago.
@Hardy,
Happy to help. Take a look at Ben Alman's jQuery plugins listed earlier in the comments; now that you are more familiar with the concept, his plugins should simplify your life a bit.
@Ben
Yes, I have seen that plugin but you know what. All those plugins make you forget (or never tell you) how it all actually works. So I like the plugins in general since they speed up our work but I also like a good Tutorial very much. That is what makes me smart at the end. All other is just convenient. Looking forward to your next Tuto. Have a good one...
I have used setTimeout() many a time, and never knew it returned a token or that you could use that to clear it! Awesome! All this time, I would have a global variable that I would set that would flag the scheduled function whether it should proceed or abort (wrap it's actions on a big if block).
This is much cleaner.
Ben....today I feel very "blocked" and maybe you can give me a hint to make it work. I use your script but I have 2 openFooterLink trigger on my site for opening the footer panel. 1 should work on mouseenter the other one on click. I just can not make it work. Can you point me? Cheers to NYC from rainy Berlin.
@Ben - I figured out on my own. It was some kind of strange. I was on the right track with creating another var for the second trigger and setting up a click function for it but it was not working because the trigger was wrapped in a <a> tag (as I found out later). It always worked with mouseenter but not with the click event. I then wrapped my trigger in a <span> tag and it all worked like a charme.
Mission completed.
I believe in love. I believe in compassion. I believe in human rights. I believe that we can afford to give more of these gifts to the world around us because it costs us nothing to be decent and kind and understanding. And, I want you to know that when you land on this site, you are accepted for who you are, no matter how you identify, what truths you live, or whatever kind of goofy shit makes you feel alive! Rock on with your bad self!
Ben Nadel