$(function(){$('.bubbleInfo').each(function(){// optionsvardistance=10;vartime=250;varhideDelay=500;varhideDelayTimer=null;// trackervarbeingShown=false;varshown=false;vartrigger=$('.trigger',this);varpopup=$('.popup',this).css('opacity',0);// set the mouseover and mouseout on both element$([trigger.get(0),popup.get(0)]).mouseover(function(){// stops the hide event if we move from the trigger to the popup elementif(hideDelayTimer)clearTimeout(hideDelayTimer);// don't trigger the animation again if we're being shown, or already visibleif(beingShown||shown){return;}else{beingShown=true;// reset position of popup boxpopup.css({top:-100,left:-33,display:'block'// brings the popup back in to view})// (we're using chaining on the popup) now animate it's opacity and position.animate({top:'-='+distance+'px',opacity:1},time,'swing',function(){// once the animation is complete, set the tracker variablesbeingShown=false;shown=true;});}}).mouseout(function(){// reset the timer if we get fired again - avoids double animationsif(hideDelayTimer)clearTimeout(hideDelayTimer);// store the timer so that it can be cleared in the mouseover if requiredhideDelayTimer=setTimeout(function(){hideDelayTimer=null;popup.animate({top:'-='+distance+'px',opacity:0},time,'swing',function(){// once the animate is complete, set the tracker variablesshown=false;// hide the popup entirely after the effect (opacity alone doesn't do the job)popup.css('display','none');});},hideDelay);});});});
Taking it Further
This effect could be perfected by changing the initial reset (popup.css())
code to read from the trigger element and approximate it’s position. In my example,
I’ve hardcoded it because I only have one on the page -
but you may want to use this effect several times across your page.