Fade in and fade out elements with jQuery

As a mostly backend developer, I am shocked at how long it could take to adjust page layout and transition with CSS/jQuery and try to learn the stuff on the go. I have struggled for probably an hour just to get a logo to display the transition effect that when you move the mouse closer, it turns to a menu button.

So I setup a div containing both the logo and the button, using jQuery’s fadeIn and fadeout method to hide the logo and show the menu button when the mouse moves into this div, and show the logo and hide the menu button when it is out.

<div id="toggle">
   <div id="logo"></div>
   <div id="menubutton"></div>
</div>

And I want one to disappear first before the second shows up. So in the Javascript code, I does this, which is causing problems.

$('#toggle').hover(function() {
    // After logo fades out, fade in the menu button
    $('#logo').fadeOut("slow", function(){
    $('#menubutton').fadeIn("slow"); 
    });
}, function() {
    $('#menubutton').fadeOut("slow", function(){
      $('#logo').fadeIn("slow"); 
    })
});

The problem here is that if you move quickly inside the interactive zone and move out quickly, jQuery will have some weird behavior. This is what I think is happening.

  1. Mouse moves in,
  2. Logo fades out, menu button is going to fade in next,
  3. Mouse moves out,
  4. jQuery tries to fade menu button out, but it is not there yet, so jQuery thinks it’s faded out already, and starts to fade in the logo.
  5. menu button now fades in
  6. So both menu button and logo are shown.

A live demo is here.

So I have to give up the ability to hide one first and then show the second because of this. Here is what I come up with.

$('#toggle').hover(function() {
    $('#logo').fadeOut("slow");
    $('#menubutton').fadeIn("slow"); 
}, function() {
    $('#menubutton').fadeOut("slow");
    $('#logo').fadeIn("slow"); 
});

However, this solution is not complete, because jQuery queues up animations. Moving in and out quickly a few times and you will see the queued animations are being executed after you stop.

A live demo is here.

At this point, what we need to do is just to stop jQuery executing queued animation, which is made easy by the stop() method.

So here is a complete solution for this. I also replaced fadeIn and fadeOut with fadeTo. But both work.

A live demo is here.

$('#toggle').hover(function() {
    $('#show').stop().fadeTo("slow", 0);
    $('#hidden').stop().fadeTo("slow", 1); 
}, function() {
        $('#hidden').stop().fadeTo("slow", 0);
    $('#show').stop().fadeTo("slow", 1); 
});
#toggle {
  border-style:solid;
    border-color:black; 
    height: 200px;
    width: 400px;
}

#logo {
    position: relative;
    float:left;
    top: 0;
    left: 0;
    height: 200px;
    width: 200px;
    background: blue;
}

#menubutton {
    display:none;
    position: relative;
    top: 0;
    left: 200px;
    height: 200px;
    width: 200px;
    background: red;
    z-index: -1
}
<div id="toggle">
   <div id="logo"></div>
   <div id="menubutton"></div>
</div>

Note that using CSS to change the opacity of the elements can achieve the same thing with, though not much, a better performance, but I would prefer to just use jQuery to solve a problem as simple as this and it provides a better cross browser support.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s