Easily Insert Footnotes or Other Comments into Your Website
Here's a method to easily insert footnotes into a website using Javascript. It degrades nicely when Javascript and/or CSS are not available for whatever reason (RSS springs to mind).
Outline
The Code
Javascript
You need the following Javascript code:
Javascript:
function insertFootnotes() {
if(!document.getElementsByTagName) return; //object detection
var spans = document.getElementsByTagName('span');
var noteIndex = 1;
for(var i=0; i<spans.length; i++) {
if(spans[i].className == 'footnote') { //are we dealing with a footnote?
var note = spans[i];
var id = 'note-' + noteIndex++; //ID of the footnote <span>
var idAnchor = id + '-a'; //ID of the footnote <a> (to expand/collapse the note)
var tmpLinkText; //get the text to be linked
for(var j=0;j<note.childNodes.length; j++) {
if(note.childNodes[j].nodeName == '#text') {
var tmp = note.childNodes[j];
if(tmp.substringData && tmp.replaceData) { //more testing to prevent errors in bad browsers
while(true) { //remove trailing spaces
if(tmp.substringData(tmp.length-1,1) == ' ') {
tmp.replaceData(tmp.length-1,1,'');
}
else {
break;
}
}
}
tmpLinkText = tmp.nodeValue;
break;
}
}
var tmpNoteText; //get the text of the footnote
for(var j=0;j<note.childNodes.length;j++) {
if(note.childNodes[j].nodeName == 'SMALL') {
tmpNoteText = note.childNodes[j].innerHTML;
break;
}
}
var okToContinue = (tmpLinkText == '' || tmpNoteText == '') ? false : true; //make sure that we actually have the information we need
if(okToContinue) {
note.innerHTML = ''; //clear the span to be safe
var link = '<a href="javascript:expand(\''+idAnchor+'\',\''+id+'\')" id="'+idAnchor+'" title="Click to expand/collapse" class="expand">'+tmpLinkText+'</a>';
var noteText = '<span id="'+id+'" class="hidden"> <span class="expand">'+tmpNoteText+'</span></span>';
note.innerHTML = link + noteText;
}
}
}
}
function expand(aID,spanID) {
if(!document.getElementById) return; //error prevention
var anchor = document.getElementById(aID);
var footnote = document.getElementById(spanID);
footnote.className = (footnote.className == 'shown') ? 'hidden' : 'shown';
anchor.className = (anchor.className == 'expand') ? 'collapse' : 'expand';
}
CSS Code
You also need the following CSS, or something similar (change to match your color scheme--my plus and minus images are 9px by 9px):
CSS:
/*
The first two rules control the display
of your footnotes; don't change them
unless you kow what you're doing
*/
.hidden {
display:none;
}
.shown {
display:inline;
}
/*
Following are the rules I use to complete the effect
*/
.expand, span.footnote small {
color: #900;
font-size:95%;
}
a.expand, a.collapse {
text-decoration:none;
font-weight:normal;
font-size:100%;
color:#900;
border-bottom: 1px dashed;
padding-left:12px;
background: url(/custom/plus.gif) no-repeat 1px;
cursor:help;
}
a.expand:hover, a.collapse:hover {
color: #900;
border-bottom: 1px solid;
}
a.collapse {
background: url(/custom/minus.gif) no-repeat 1px;
}
span.expand a, span.expand a:hover {
font-weight:normal;
color: #900;
}
Explanation (or, skip to the usage instructions)
Function insertFootnotes
Javascript:
function insertFootnotes() {
if(!document.getElementsByTagName) return; //object detection
var spans = document.getElementsByTagName('span');
var noteIndex = 1;
for(var i=0; i<spans.length; i++) {
This function creates our footnotes. This way, we don't have to type all that footnote code by hand every time we want a footnote. First, we initialize a few variables and loop through all <span> elements in the document.
Javascript:
if(spans[i].className == 'footnote') { //are we dealing with a footnote?
var note = spans[i];
var id = 'note-' + noteIndex++; //ID of the footnote <span>
var idAnchor = id + '-a'; //ID of the footnote <a> (to expand/collapse the note)
var tmpLinkText; //get the text to be linked
See the comments in the code above.
Javascript:
for(var j=0;j<note.childNodes.length; j++) {
if(note.childNodes[j].nodeName == '#text') {
var tmp = note.childNodes[j];
if(tmp.substringData && tmp.replaceData) { //more testing to prevent errors in bad browsers
while(true) { //remove trailing spaces
if(tmp.substringData(tmp.length-1,1) == ' ') {
tmp.replaceData(tmp.length-1,1,'');
}
else {
break;
}
}
}
tmpLinkText = tmp.nodeValue;
break;
}
}
For each footnote, we're looking for the text that should become a link. We find the first text node that is a child of our footnote <span> and strip out any trailing whitespace in browsers that know how to do it.
Javascript:
var tmpNoteText; //get the text of the footnote
for(var j=0;j<note.childNodes.length;j++) {
if(note.childNodes[j].nodeName == 'SMALL') {
tmpNoteText = note.childNodes[j].innerHTML;
break;
}
}
Next, we find the text of the footnote. It is in a SMALL tag (this is so that the footnote will still be set apart when your page is viewed without Javascript or your stylesheet; e.g., in your RSS feed).
Javascript:
var okToContinue = (tmpLinkText == '' || tmpNoteText == '') ? false : true;
if(okToContinue) {
Sanity check to make sure we don't destroy something in case there were problems.
Javascript:
note.innerHTML = ''; //clear the span to be safe
var link = '<a href="javascript:expand(\''+idAnchor+'\',\''+id+'\')" id="'+idAnchor+'" title="Click to expand/collapse" class="expand">'+tmpLinkText+'</a>';
var noteText = '<span id="'+id+'" class="hidden"> <span class="expand">'+tmpNoteText+'</span></span>';
note.innerHTML = link + noteText;
Finally, we make our changes to the HTML so that our footnotes look like footnotes. After this, we jump back to the top of our loop and find the next <span class="footnote">.
Function expand
Javascript:
function expand(aID,spanID) {
if(!document.getElementById) return; //error prevention
var anchor = document.getElementById(aID);
var footnote = document.getElementById(spanID);
footnote.className = (footnote.className == 'shown') ? 'hidden' : 'shown';
anchor.className = (anchor.className == 'expand') ? 'collapse' : 'expand';
}
This function is called whenever the user clicks on a footnote link. It receives two parameters: the ID of the link and the ID of the footnote itself. Then it simply toggles the CSS classnames. The class hidden sets display: none and class shown sets display: inline. The expand and collapse classes on the links control the display of the icons and take care of switching them.
Usage Instructions
Installation
- Put the CSS code either in an external CSS file or in the
<head>section of your (X)HTML file. - Customize the CSS to suit your needs. You can easily make your own 9px × 9px expand/collapse boxes, or you can copy mine to your server and use them (please don't steal my bandwidth by linking directly to my images). Here they are:
.
- Put the Javascript code either in an external Javascript file or in the
<head>section of your (X)HTML file. - Call
insertFootnotes()onload. Here's one way to do it:Javascript:
window.onload = function () {
insertFootnotes();
//other onload stuff goes here
}
Usage
Surround the footnote link text and the footnote itself with <span class="footnote"></span>. Then, surround the footnote text with <small></small> (why? We use <small> so that those who view your page without your CSS code will still see a difference between regular text and footnote text. Also, <small> probably won't be used for any other purpose and cause a conflict.). Perhaps an example will help. This code:
Here's the before-text. <span class="footnote">Link text <small>(This is the footnote text.)</small></span> Here's some after text.
And here it is in action:
Here's the before-text. Link text (This is the footnote text.) Here's some after text.
Comment by TabathaOster
May 18, 2006 @ 9:58 am
Awesome blog. Peace out until next time TabathaOster