Dynamically Conjuring Drop-Down Navigation
by Christian Heilmann Published in CSS, HTML, Javascript, Interaction Design ∙ 38 Comments
Wouldn’t it be great to allow our users to reach all the pages of our site via a handy drop-down menu — without expending extra effort adding one to each page?
We can, by harnessing the powers of a seemingly forgotten HTML element and adding a tap of our JavaScript wand (or a drop of a less magical PHP potion).
The missing link
The LINK element is part of the HEAD section of an HTML document, and provides links to other documents (including style sheets). Some browsers use its data to show a toolbar — alas, the son of the giant of Redmond does not, and his followers are legion.
Let’s teach it what to link
If we want to link to several articles, an appendix, the table of contents, and the first, next, and previous documents, then our HTML might contain something like this:
<link
rel="StyleSheet"
href="styles.css"
type="text/css"
media="screen"
/>
<link
rel="StyleSheet"
href="print.css"
type="text/css"
media="print"
/>
<link
rel="Chapter"
href="chapter1.html"
title="Chapter 1"
/>
<link
rel="Chapter"
href="chapter2.html"
title="Chapter 2"
/>
<link
rel="Chapter"
href="chapter3.html"
title="Chapter 3"
/>
<link
rel="Chapter"
href="chapter4.html"
title="Chapter 4"
/>
<link
rel="Chapter"
href="chapter5.html"
title="Chapter 5"
/>
<link
rel="Chapter"
href="chapter6.html"
title="Chapter 6"
/>
<link
rel="Appendix"
href="links.html"
title="A. Useful Articles"
/>
<link
rel="Start"
href="index.html"
title="Start page"
/>
<link
rel="Contents"
href="toc.html"
title="Table of Contents"
/>
<link
rel="next"
href="chapter4.html"
title="next: chapter 4"
/>
<link
rel="prev "
href="chapter2.html"
title="previous: chapter 2"
/>
The JavaScript
Our ideal script should be:
- Unobtrusive. The drop-down menu should only be conjured when it can be populated and linked to the documents.
- Customizable: We want to define which elements should be added and what their labels and values are — and we want to be able to position the drop-down menu in our pages using CSS and markup rather than JavaScript.
- Reusable: All we want to do is embed it in the HEAD via a SCRIPT tag
Let’s start with the variables for customization and check to see if the DOM is available.
function showlinks() {
var elementid='linksnavigation';
var elementtype='div';
var dropdownlabel='Quick Jump to:';
var dropdownbutton='jump';
var dropdownid='linksnavigationdropdown';
if(
document.getElementById&&document;.createTextNode
) {
Next, we grab any LINK elements (while checking to see if there are any). If there are links, we initialize the variables we use (to avoid overwriting global variables).
pagelinks =
document.getElementsByTagName('link');
if(pagelinks.length>0) {
var ispage,
linksgen,
pagelinks,
linksdiv,
linksform,
count;
var linkslabel,
linkssel,
linkssubmit,
newop,
relatt,
sel;
var count=0;
Then we check to see if the parent element of our drop-down already exists. If not, we create it.
if(document.getElementById(elementid)) {
linksgen=false;
linksdiv=document.getElementById(elementid);
} else {
linksgen=true;
linksdiv=document.createElement(elementtype);
linksdiv.setAttribute('id',elementid);
}
Now it is time to create our form.
linksform=document.createElement('form');
linkslabel=document.createElement('label')
linkslabel.appendChild(
document.createTextNode(dropdownlabel)
);
linkslabel.setAttribute('for',dropdownid);
linkssel=document.createElement('select')
linkssel.setAttribute('id',dropdownid);
linkssubmit=document.createElement('input');
linkssubmit.setAttribute('type','submit');
linkssubmit.setAttribute('value',dropdownbutton);
To populate the drop-down options, we loop through all the LINK elements and
read their title and href attributes. As we don’t
want to link to style sheets, we filter them out. Then we compare the href
data to the current page to automatically offer the next page as the highlighted option.
for(i=0;i.getAttribute('rel'); if(!/sheet/i.test(relatt)) { newop=document.createElement('option'); newop.appendChild( document.createTextNode( pagelinks<i>.getAttribute('title') ) ); newop.setAttribute( 'value',pagelinks<i>.getAttribute('href') ); if( document.location.href.indexOf( pagelinks<i>.getAttribute('href') ) != -1 ) { ispage=count; } linkssel.appendChild(newop) count++; } } linkssel.selectedIndex=ispage?ispage:0;
Then we need to tell the form what to do once it gets submitted. In our case, we take the value of the selected option and set the window location to this value.
linksform.onsubmit=function() {
sel =
document.getElementById(dropdownid);
self.location =
sel.options[sel.selectedIndex].value;
return false;
};
Time to assemble the form.
linksform.appendChild(linkslabel); linksform.appendChild(linkssel); linksform.appendChild(linkssubmit); linksdiv.appendChild(linksform);
Now we check to see if the linksdiv element has to be created or not,
and add it to the start of the document if needed.
if(linksgen) {
document.body.insertBefore(
linksdiv,document.body.firstChild
);
}
}
}
}
Now we just need to call our script when the page is loaded. For
that, we can use window.onload or use a
script
to add our function to other onload events, bearing in mind that the script
option is cleaner, but doesn’t work on some browsers.
window.onload=showlinks
And that is all. See it in all its glory. (The demo page includes the JavaScript in a text file and a downloadable zip with everything you’ll need to get started.)
But isn’t JavaScript dark magic?
True, JavaScript can be turned off, and we cannot take it for granted. However, we are simply enhancing our document with JavaScript to make up for browser failings.
If we want to offer this functionality without JavaScript, we need to move our efforts to the server side, for example via PHP.
The download pack for this article contains a PHP script that does exactly that. All we need to do is to feed it the HTML document as a parameter.
Our foo page
This script takes the link data and assembles a form that will be placed
either inside the element when it is already there, or directly after the
<body> element if it isn’t.
The form links to the script itself to send the browser to the chosen page.

38 Reader Comments
Load Comments