Everything Photoshop Subscribe

How To Create A Keypress Navigation Using jQuery

In Javascript / AJAX by Bedrich Rios
The key to a succesful website is the ease with which a user finds what they are looking for. Thus, it's worth spending a lot of time and effort in creating both useful and visually appealing navigation systems. Lately, I have began experimenting with new ways to navigate a website. In this tutorial I'll show you how to let the user make use of their keyboard to get around your site.

Step 1

The first thing we need to do is create our test page. In this case, I will refer to it as demo.html and it will contain the following:
  1. A link to the jQuery framework.
  2. A link to the script we will work on later. Let's call it keypress_nav.js
  3. A link to a CSS file called style.css (we will also work on this later).
  4. A header div that will contain our navigation among other things. And
  5. Five unique div elements that will serve as pages for our site.
So, here is what demo.html looks like at this point:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
	<head>
		<title>KeyPress Navigation Demo</title>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
		<link rel="stylesheet" type="text/css" href="style.css" />
		<script type="text/javascript" src="jquery.js"></script>
		<script type="text/javascript" src="keypress_nav.js"></script>
	</head>
	<body>
		<div id="header">
			<!-- Our navigation will go here -->
		</div>
		<div id="home">
			<h2>Welcome!</h2>
			<p>Some Text</p>
		</div>
		<div id="about">
			<h2>About Me</h2>
			<p>Some Text</p></p>
		</div>
		<div id="contact">
			<h2>No Spam Please</h2>
			<p>Some Text</p>
		</div>
		<div id="awards">
			<h2>Awards, So Many ...</h2>
			<p>Some Text</p>
		</div>
		<div id="links">
			<h2>Cool Sites</h2>
			<p>Some Text</p>
		</div>
	</body>
</html>

Step 2

Now that we have our DIVs in place, we can go ahead and create the navigation for the page. As you may have guessed, we will be using an unordered list <ul> to hold the links and the DIV's IDs as the targets for these links. Also, we will add the class container to all the DIV "pages." This class will help us easily refer to these DIVs when we create our script. So, here is what you should have now:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
	<head>
		<title>KeyPress Navigation Demo</title>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
		<link rel="stylesheet" type="text/css" href="style.css" />
		<script type="text/javascript" src="jquery.js"></script>
		<script type="text/javascript" src="keypress_nav.js"></script>
	</head>
	<body>
		<div id="header">
			<ul id="navigation">
				<li><a href="#home">Home ( a )</a></li>
				<li><a href="#about">About ( s )</a></li>
				<li><a href="#contact">Contact ( d )</a></li>
				<li><a href="#awards">Awards ( f )</a></li>
				<li><a href="#links">Links ( g )</a></li>
			</ul>
		</div>
		<div id="home" class="container">
			<h2>Welcome!</h2>
			<p>Some Text</p>
		</div>
		<div id="about" class="container">
			<h2>About Me</h2>
			<p>Some Text</p></p>
		</div>
		<div id="contact" class="container">
			<h2>No Spam Please</h2>
			<p>Some Text</p>
		</div>
		<div id="awards" class="container">
			<h2>Awards, So Many ...</h2>
			<p>Some Text</p>
		</div>
		<div id="links" class="container">
			<h2>Cool Sites</h2>
			<p>Some Text</p>
		</div>
	</body>
</html>
Note: The letter (key) inside the parenthesis is the key we will later use as navigation for our page.

Step 3

The structure of our test page is now complete but lacking visual appeal. So, let's add some CSS and jazz it up. One thing to keep in mind before we begin the styling is that our page must look good even if JavaScript is turned off. Scripts, in my opinion, should always be used as a bonus to those users who have JavaScript turned on but should not alienate those who don't. We are web designers/developers after all, and we care about usability, right?

You can see the look we're going for in the screenshot above. It's simple and uses some nice, bold colours to highlight the different sections. So here's our CSS:

body 
{
	margin: 0;
	padding: 0;
	font-family: "Lucida Grande", "Lucida Sans", sans-serif;
	font-size: 100%;
	background: #333;
}


/* Header
-------------------------------------------------- */

#header
{
	width: 460px;
	margin: 0 auto;
	font-size: .75em;
	font-family: "Helvetica Neue", Helvetica, sans-serif;
}

#header ul 
{
	list-style: none;
	margin: 0;
	padding: 0;
}

#header ul li 
{
	float: left;
	text-align: left;
}

#header ul li a
{
	display: block;
	color: #ffff66;
	text-decoration: none;
	text-transform: uppercase;
	margin-right: 20px;
}

#header ul li a:hover
{
	text-decoration: underline;
	color: #ffcc66;
}


/* Containers
-------------------------------------------------- */

.container
{
	width: 400px;
	height: 300px;
	margin: 30px auto;
	padding: 10px 20px;
	border: 10px solid #fff;
	color: #fff;
	font-size: .75em;
	line-height: 2em;
}

.container h2
{
	padding: 5px 10px;
	width: 200px;
}

#home		{ background: #15add1; }
#home h2	{ background: #007aa5; }
#about		{ background: #fdc700; }
#about h2	{ background: #bd9200; }
#contact	{ background: #f80083; }
#contact h2	{ background: #af005e; }
#awards		{ background: #f18300; }
#awards	h2	{ background: #bb5f00; }
#links		{ background: #98c313; }
#links h2	{ background: #6f9a00; }


/* Self-Clearing Rules 
-------------------------------------------------- */

ul#navigation:after 
{
    content: ".";
    display: block;
    visibility: hidden;
    clear: both;
    height: 0;
}

* html ul#navigation 	{ height: 1px; }
ul#navigation 			{ min-height: 1px; }
Note: I have added some self-clearing rules to the navigation in order to work around its lack of height due to its inner floated elements. In other words, margin rules from the upper most container will now have the proper effect on the navigation <ul>.

Step 5

At this point in the tutorial you should have a page looking something like this:
Test Page Preview
It is a functional page and it works properly without the need for JavaScript to be turned on. However, as I said before, let's give a little bonus to those users who do have JavaScript turned on on their browsers. We will do this in two steps. Firstly, we will create two functions that will hide and display the pages appropiately. And secondy, we will add some some code to determine the keys pressed by the user. Let's now create a file called keypress_nav.js and get to work on our functions.

Step 6

We are going to need two functions for our script to work as desired. One of the functions will be called when the user presses one of our predetermined navigation keys (The letters in parenthesis from Step 2) and will hide all other containers displaying only the DIV associated to this key. This is what our first function looks like:
function showViaKeypress(element_id)
{
	$(".container").css("display","none");
	$(element_id).slideDown("slow");
}
Now, our second function will take an array of links and assign them on click target functions. In other words the function will get our navigation links, retrieve the "href" attribute and display the appropiate DIV upon clicking it. So, here is what the second function looks like:
function showViaLink(array)
{
	array.each(function(i)
	{	
		$(this).click(function()
		{
			var target = $(this).attr("href");
			$(".container").css("display","none");
			$(target).slideDown("slow");
		});
	});
}

Step 7

Now that we have our functions coded, we need to call them appropiately when the page loads. The first thing we need to do is hide all the elements that have class container with the exception of the DIV that has the ID home. Next, we need to call the showViaLink() function with the links inside of our navigation <ul> as its parameter. Last but not least, we have to listen for the user keypress and call the showViaPress() function with the appropiate ID as its parameter. This can be accomplished by using a switch on the key pressed.

The switch will have 5 cases (one for every link) and its number corresponds to the ASCII number for the keypress. For example, if the "a" key is pressed, switch will use case 97. So, here is what the code looks like:

$(document).ready(function()
{
	// hides all DIVs with the CLASS container
	// and displays the one with the ID 'home' only
	$(".container").css("display","none");
	$("#home").css("display","block");
	
	// makes the navigation work after all containers have bee hidden 
	showViaLink($("ul#navigation li a"));
	
	// listens for any navigation keypress activity
	$(document).keypress(function(e)
	{
		switch(e.which)
		{
			// user presses the "a"
			case 97:	showViaKeypress("#home");
						break;	
						
			// user presses the "s" key
			case 115:	showViaKeypress("#about");
						break;
						
			// user presses the "d" key
			case 100:	showViaKeypress("#contact");
						break;
						
			// user presses the "f" key
			case 102:	showViaKeypress("#awards");
						break;
						
			// user presses the "g" key 
			case 103:	showViaKeypress("#links");
		}
	});
});

Step 8

Now that we have all the pieces of the puzzle, we can put it together. Here is what the final iteration of our script should look like:
$(document).ready(function()
{
	// hides all DIVs with the CLASS container
	// and displays the one with the ID 'home' only
	$(".container").css("display","none");
	$("#home").css("display","block");
	
	// makes the navigation work after all containers have bee hidden 
	showViaLink($("ul#navigation li a"));
	
	// listens for any navigation keypress activity
	$(document).keypress(function(e)
	{
		switch(e.which)
		{
			// user presses the "a"
			case 97:	showViaKeypress("#home");
						break;	
						
			// user presses the "s" key
			case 115:	showViaKeypress("#about");
						break;
						
			// user presses the "d" key
			case 100:	showViaKeypress("#contact");
						break;
						
			// user presses the "f" key
			case 102:	showViaKeypress("#awards");
						break;
						
			// user presses the "g" key 
			case 103:	showViaKeypress("#links");
		}
	});
});

// shows a given element and hides all others
function showViaKeypress(element_id)
{
	$(".container").css("display","none");
	$(element_id).slideDown("slow");
}

// shows proper DIV depending on link 'href'
function showViaLink(array)
{
	array.each(function(i)
	{	
		$(this).click(function()
		{
			var target = $(this).attr("href");
			$(".container").css("display","none");
			$(target).slideDown("slow");
		});
	});
}

Demo

Take a look at the script in action on this demo page.
The pattern used in this demo was made by Taylor Satula.
Enjoyed this post? Your vote is always appreciated!! Delicious StumbleUpon Float Digg

Comments

Leave a Comment
  1. Very nice idea but I cant think of many websites if any that utilize this.

    Andrew Pryde

  2. “Very nice idea but I cant think of many websites if any that utilize this. ”

    ??? I thought that would make it better and more impressive….

    My only reservation is that outside the hardcore geek community used to working at the CLI, I don’t know many people who are that concerned about keeping their hands off the mouse.

    But a good idea well implemented. Thank you.

  3. Great tut! Thnx a lot. Best wishes from Russia/.

  4. Andrew, first - why include your name and URL? It’s already in your comment. Shameless. Anyway, I think keypress navigation will get more popular as the distinction between desktop and web applications vanishes.

  5. Cool tutorial, I like it if I will use the mouse only.

    When it comes to navigation online, most of users prefer to use mice and no keyboards. Keyboards only for filling forms and we usually (developers) try to minimize that by making forms short and easy.

  6. Thanks for this post and this site!

  7. very useful and nice technique. thanks a lot Bedrich!

  8. Good tutorial, thanks :)

  9. Gravatar

    Mark Bowen

    Nice tutorial,

    Perhaps you should also add in accesskey support too?

    Best wishes,

    Mark

  10. Great tutorial! Very useful.
    I also like the sliding on this one.
    Thanks Bedrich! Your tutorials are the best!

  11. Cool tut.. thanx

  12. Very smooth. One thing though, if you press one link and then another one before the other has finished loading, they will both appear on the screen at the same time. (Mac OS X - Firefox RC1).

    If you can solve this, it will be interesting to see how you’ve done it, because I have a jQuery technique that is suffering from a similar issue. Is there an “animating” event or something?

  13. Gravatar

    Johan Munk

    Hey there, i like the tutorial, although i might not getting around to using it.
    Anyway, i ran into a problem. The script won’t work in ff if you’ve got quick find turned on (searching for text, as i type), while it will change pages on the first click, but not on the second and so forth.

  14. very nice tutorial, the frequency of publication is increasing, very nice

  15. Good to see another tutorial on jQuery - one of my favourite things at the moment.

    Whilst it’s all very interesting, practically speaking I can’t say it’s something that I can see myself using, but thanks for posting nonetheless.

  16. Great tutorial, thanks. I’ve been looking for this quite some time.

    Is there a possibility to add in support for the browser’s back button? When a user presses ‘Back’, the previous div is being loaded… Such an addition would rock!

  17. wow, nice effect. When I saw this, I remember the way gmail works ^^

  18. Great tutorial and effect, but I’m afraid the behaviour of the browsers back-button will confuse many normal surfers.
    Anyway, nice!

  19. Great tutorial and effect, but I’m afraid the behaviour of the browsers back-button will confuse many normal surfers. Anyway, nice!

  20. You mean you guys don’t know the benefit of keyboard shortcuts? Any developer loves shortcuts. Pressing a key for an action is much faster and more efficient than clicking things with the mouse. I know I love learning shortcuts in all the programs I use.

  21. Pretty cool, to use within a section of your site. You might want to check it, as it does break and displays 2 elements if you toggle quick enough with the mouse. Best way to test something is to try and break it, and it seems that this technique breaks when using the mouse(displays your last 2 choices). When using only the keys it will display only the last key you pressed but if you toggle quick enough you can see the all the pressed elements for a small moment.

  22. It would be nice to have a link at the TOP of the tutorial so that we can have a better idea of what it’s all about.

  23. Hey this could be an awesome new concept in online surfing… who knows huh. Great article!

  24. Great idea!

    This is a great tutorial! Thanks.

    David Carreira

  25. hmm, not half bad

  26. Great idea, but won’t work if a user has “Search when I start typing” enabled on a browser (ie. Firefox 3). I agree with Mitch that most users (non-developers, which makes up about 99.9% of users) don’t use shortcuts when browsing.

    Good looking, none the less.

  27. I have been using this concept to make a link appear appear as the default button in a form for a while now. Thanks for posting this here and am sure a lot of my fellow web developers will learn from this. :)

  28. Gravatar

    InLikeALion

    I second the idea that all nettuts.com posts should have a demo link at the top. That’s just better user experience, and common sense. I hate having to scroll to the bottom to find out what I’m going to be reading about.

    Other than that nitpick, I’m glad you guys have been showcasing some simple jQuery stuff in easy to understand tutorials. I’ve been reading nettuts for only a few weeks now, but have been really impressed with the write-ups, subjects, and frequency of interesting information. Thanks a lot!

  29. Well, nice article, but you’re missing something, when the user press the same key over and over again….

  30. Nice tutorial. Even without the key shortcuts, the effect is something I’m going to be using on a new site. thanks for keeping this site with fresh content that is actually worth something :)

  31. Thanks for the clarity of execution in your tut.

    One thing: I wish the links changed state to show where you are in the navigation. When they stay perpetually normal (even when active) I think it’s easy for a user to get lost.

    What’s the easiest way to remedy that, if indeed one wanted to?

    Thanks!!

  32. I had seen this on a website a while back but forgot all about it. This is a great sample and there are huge positive implications in using this…I gotta run but might come back and write more…thanks.

  33. Hey Thats My Background Pattern Why Did I Get No Credit!!!!!
    Somebody ANSWER WHY!!!

  34. @Taylor

    Sorry for giving you no credit for the pattern. I will do so right now. A friend of mine gave me a set of patterns not so long ago and I thought they were all royalty free, obviously I was wrong. Sorry.

  35. Links being posted no prob

  36. Cute but doesn’t work on FireFox!

  37. I mean the keypress part

  38. Oops I was wrong! if u want u can delete my other comments!
    Its workin on FF too! but I think there is a bug when u click on second link just after 1st one… it shows both of them!

  39. Of course it’s running on Firefox, even better than on any other browser

  40. Just a small thing here - but it’s Firefox.

    It doesn’t have a capital F in the middle. :)

  41. Thanks for the information.

  42. nice tutorial, this breaks though when using the mouse. when clicking instead of using the keys you will be able to see the last 2 elements that were clicked on.

  43. Very nice. I can see this coming in very handy for some apps I do that require some heavy data entry.

  44. If you click the links very fast the other’s div doesn’t gets hidden in firefox…please fix this..

  45. Very useful tutorial. Thank you

  46. Firefox renders almost everything correctly. I’m in love with Firefox, but it burns me when I code a site, I’m like “Sweet, all done, looks rad and everything. Oh hey, let’s not forget to check IE.”

    Starts IE. Loads web-site.

    “^!@%$^%!@$.”

  47. Very nice. This will be nice if I get a client that needs a hyper-super-accessible site!

  48. If you’ve got “find as you type” turned on in Firefox (which everyone should) it breaks on the second attempt. The first keypress works but the second doesn’t as FF tries to do a find rather than registering the keypress. Not really a fault of the code but more of a limitation of keypress navigation.

  49. Very nice tutorial, I love jquery, but find it hard to use at times.

  50. Really nice. Thanks

  51. it’s a great tutorial, but (without reading all of the comments), there’s an obvious bug. clicking quickly on the links creates multiple tables, it doesn’t redo a single one. pressing the shortcuts quickly does the same, but when they’re done spreading down, it only keeps one.

  52. I haven’t seen that kind of S3 hosting before, how does it work? Is it a combination of S3 and EC2?

  53. A beauty. Only thing I’d change is have the subsequent event’s kill the previous events and animation. That way you don’t have everything animating all at once if you pressed all keys very quickly.

  54. Nice tut. However there is a bug with this. If you click one link after the other very quickly then it will show you the contents of both nav links. So it would be nice if the one that did this tut can fix this.
    Overall nice tut. =)

  55. A completely useless tool, as a user generally will not spend enough time on your portfolio to actually make use of these “faux accesskeys.” Of course, these are only useful on portfolios, as high-profile websites will either have too many pages to have use of these, or not want to use tabs at all. I heartily agree with both. So again, this is a useless tutorial.

  56. Hey, what would the JQuery code be like if we wanted it to be just links and no keypress? I’m new to jquery :)

  57. Awesome Tutorial. Thx NetTuts.

  58. You can have shorten the tutorial to :
    # $(document).keypress(function(e)
    # {
    # switch(e.which)
    # {
    # // user presses the “a”
    # case 97: showViaKeypress(”#home”);
    # break;
    #
    # // user presses the “s” key
    # case 115: showViaKeypress(”#about”);
    # break;
    #
    # // user presses the “d” key
    # case 100: showViaKeypress(”#contact”);
    # break;
    #
    # // user presses the “f” key
    # case 102: showViaKeypress(”#awards”);
    # break;
    #
    # // user presses the “g” key
    # case 103: showViaKeypress(”#links”);
    # }
    # });

    Because this is the only interesting part in an article named aimed at “Keypress navigation”.

    To handle the problem with multiple div showing when clicking fast :
    #function showViaLink(array)
    #{
    # array.each(function(i)
    # {
    # $(this).click(function()
    # {
    # var target = $(this).attr(”href”);
    # $(target).css(’height’,'300px’).slideDown(0);
    # $(”.container”).not($(target)).stop().hide();
    # });
    # });
    #}

    Bye !

  59. Problem in IE7: There’s an issue with IE7 where when the page is refreshed, sometimes there’s a moment when the hidden elements show up (sort of like a flicker). I haven’t had much luck with this issue, and the problem stems from IE7 being sluggish in processing the .css("display", "none").

    One workaround that I can think of is to assign the display: none attribute in the stylesheet instead of using jQuery, then select the first div, and assign it an attribute of display: visible or use .show() to show it initially. Something like: $('#home').css('display', 'visible') or $('#home').show()

    The problem with this method: Poor degradation in the JS off / CSS on scenario, where you won’t see any of the div’s. So I would prefer not to do that.

    If anyone out there can find a solution to this, I’d love to hear it.

  60. Hi…
    I am now with a big trobule…
    When some one clicks the menu, its doesn’t stays in same place.
    It gets left about 20px.
    Have removed most the Css and nothing worked.

  61. Nice tutorial.

    However, it should probably detect if the user is typing in a form. Since most contact pages would have a form on them, it would be troublesome to have it disappear whenever you type an A, S, D, F, or G.

  62. Nice tutorial!

    I have a problem with IE7. I can view demo in IE7. I can use my code in FireFox. But I cannot use my code in IE7.

    any advice?

    Thx.

  63. Great techniques. Thanks alot

Add a Comment

Note: We use Gravatars on NETTUTS, they are little icons that appear next to your name on this site and on many others. You can get a Gravatar account for free and any other site that supports it will show your avatar too!

 

Trackbacks

Leave a Trackback