Learning jQuery: Fading Menu – Replacing Content

* 4/9/2008  —  30 Comments *

by: Chris Coyier

fadingmenu.png

The more I learn about jQuery, the more natural it feels. Probably because of how closely tied to CSS it is. From a design perspective, the syntax for jQuery is:

“When I do this, make the CSS do this.”

So now instead of thinking about CSS as page layout and a way to style your page when it loads, you can use in animation and change it on-the-fly to react to events that happen on your page. Take for example a menu. You can take the “click” event that happens when clicking on a menu to do lots of stuff.

 

View Demo   Download Files

 

This example page has three menu items and three content areas: home, about, and contact. By default, the home button is selected, meaning that it’s menu graphic is at full opacity and it’s content area is shown:

#home {
	display: block;
	padding: 30px;
}
#home-button {
	opacity: 1.0;
	border-bottom: 1px solid black;
}

By default, the other menu items are faded and their content areas are hidden, like so:

#about {
	display: none;
	padding: 30px;
}
#about-button {
	opacity: 0.5;
	border-bottom: 1px solid black;
}

With jQuery, we can listen for that click event and then act accordingly. This is what we want to happen:

  • Fade IN the menu item being clicked on.
  • Fade OUT all other menu items.
  • DISPLAY the corresponding content area.
  • HIDE all other content areas.

Since the home button is active by default, let’s look at the jQuery javascript for the about button:

<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript">
	$(document).ready(function(){
		$("#about-button").click(function(){
			$(this).animate({
				opacity: 1.0,
				borderWidth: 5
			}, 600 );
			$("#home")
				.css({
					display: "none"
				});
			$("#about")
				.css({
					display: "block"
				});
			$("#contact")
				.css({
					display: "none"
				});
			$("#home-button").animate({
				opacity: 0.5,
				borderWidth: 1
			}, 600 );
			$("#contact-button").animate({
				opacity: 0.5,
				borderWidth: 1
			}, 600 );
		});
	});
</script>

Your complete javascript code would have similar chunks for all three buttons. As I’ve mentioned before, I’m just learning here, so there is likely to be a way smarter way of writing this, but these are the basics and they work.

UPDATE:

This is way smarter:

$("#page-wrap div.button").click(function(){

	$clicked = $(this);

	// if the button is not already "transformed" AND is not animated
	if ($clicked.css("opacity") != "1" && $clicked.is(":not(animated)")) {

		$clicked.animate({
			opacity: 1,
			borderWidth: 5
		}, 600 );

		// each button div MUST have a "xx-button" and the target div must have an id "xx"
		var idToLoad = $clicked.attr("id").split('-');

		//we search trough the content for the visible div and we fade it out
		$("#content").find("div:visible").fadeOut("fast", function(){
			//once the fade out is completed, we start to fade in the right div
			$(this).parent().find("#"+idToLoad[0]).fadeIn();
		})
	}

	//we reset the other buttons to default style
	$clicked.siblings(".button").animate({
		opacity: 0.5,
		borderWidth: 1
	}, 600 );

});

 

View Demo   Download Files

 

Responses

  1. Adrian says:

    Nice Chris. In FF 2 the cursor is default on hover though. Maybe a quick cursor:pointer can be thrown into the CSS.

  2. b0li says:

    i like jQuery
    cheers mate

  3. Flavia says:

    This is truly nice, Chris.
    Now I’ve got to come up with a new project to experiment with jQuery.
    And it’s your fault.

    …and I thank you – in uppercase – for this :)

  4. Romz says:

    Hello Chris,

    Maybe a better way to perform your animation :
    $(document).ready(function(){
    $(”#page-wrap div.button”).click(function(){

    if($(this).css(”opacity”) != “1″)
    {
    $(this).actualBtn.animate({
    opacity: 1,
    borderWidth: 5
    }, 600 );
    }

    $(this).siblings().animate({
    opacity: 0.5,
    borderWidth: 1
    }, 600 );

    });
    });

    You probably have to do some enhancements to filter the showed content div but it’s not a big deal for you I guess.
    If you want, I’ll do it

  5. David Sparks says:

    Sweet. I’m in the process of learning jQuery myself so glad you’re doing some here

  6. David Walsh says:

    Nice work Chris. My only suggestion would be to speed up the duration. Awesome though!

  7. Joe says:

    jQuery is by far my preferred javascript library of choice and here is another example of why. Well done.

  8. Eoin says:

    Hmm, the content slides up and down with the thickness of the underlining black bar, in Firefox at least.

  9. David Madden says:

    Thanks for another good jQuery post.

  10. Nice post Chris, I would also suggest maybe tying in the history plugin for jquery so that you can still use the next and back buttons.

    Your skills are improving :)

  11. Steve says:

    Anyone know how to fade in a background image on MouseOver on a LI element, and obviously fade out the background on MouseOut? I’ve been searching for jQuery code, and all I found was one that dealt with color only.

  12. Jason says:

    The border “jumps” the first time you select a button in FF. Any ideas how to fix that?

  13. Jason says:

    What about internet explorer? It doesn’t function quite right there. You have to click twice for things to start working.


    Jason

  14. Rob says:

    If the colours are changed for the text in the css, when returning in Firefox and Safari (possibly IE), the text’s opacity is down. Any ideas?

  15. good work!
    i am looking for a fade for dynamic content. i mean, i am loading external content from external serverside file in a div and this loading should be fading when loading. is there any work like what i want?

  16. GreyK50 says:

    Jquery really help us alot man… I mean for web designer like me.. zero knowledge in JAVA but hey!~ Jquery do all the neatto effects and stuff!!!
    Thanks for sharing this… (salute)