Generating Automatic Website Footnotes with jQuery

I spent a lot of time (7 long years) in academia, writing about technical communication and new media. During that time, I created many academic documents for the web. A lot of those documents had footnotes. Generating footnotes for HTML documents in the past was always a slow, painful task — and every time I did it, I wondered why there wasn’t a better, easier way.

Today, I’m happy to announce that I’ve come up with a better solution to web footnotes using the jQuery JavaScript framework and a few tags and attributes that already exist in XHTML. And I’m even happier to show you how to do it! If you’d like to see it in action before we begin, go here.

The Problem:

  • Many websites could benefit from having footnotes, but…

  • Manually creating footnotes for web documents is a slow process.

The Requirements:

  • Creating the footnotes should be as painless as possible (i.e., make use of as many standard tags/attributes as possible).
  • Users should be able to create footnotes that are pure commentary, book citation, web reference, or any combination thereof.

The Solution:

I decided to make use of the two most common XHTML tags that might need footnote information: blockquotes and quotations (<q>). Both of those tags can take the “cite” attribute, whose value is the URL from which the quoted material originated.

<q cite="http://www.cssnewbie.com/">
	Rob Glazebrook of CSSnewbie is imminently quoatable.
</q>

That takes care of the URL portion of our requirements… but what about commentary-type asides or non-web citations? You can’t put those in the cite attribute, because the only acceptable value for that attribute is a URL, and any comments you put in will be rendered as such in the output (it’s ugly… trust me). So for comments and other reference material, let’s turn to the “title” attribute instead.

<q title="Done with your TPS reports?">
	Is this good for the company?
</q>

And if you’d like your footnote to look more like a standard-issue reference citation, you could even put markup inside your title.

<q title="Zeldman, Jeffrey. <em>Designing with
Web Standards</em> New Riders, 2003.">
	We build only to rebuild.
</q>

Admittedly, sticking XHTML markup in your title tag is pretty bad practice, so I can’t say that I 100% recommend this tactic… but I’ve tested it, and it works (at least in XHTML Transitional).

So now that we know what our XHTML looks like, let’s turn to the jQuery!

$(document).ready(function() {
	$("#wrap").append("<ol id=\"footnotes\"></ol>");
	footnote = 1;
	$("q[cite],q[title],blockquote[cite],blockquote[title]").addClass("footnote");
	$(".footnote").each(function() {
		$(this).append("<sup>"+footnote+"</sup>");
		cite="<li>";
		url=$(this).attr("cite");
		title=$(this).attr("title");
		if(title && url) {
			cite+="<a href=\""+url+"\">"+title+"</a>";
		} else if(title) {
			cite+=title;
		} else if(url) {
			cite+="<a href=\""+url+"\">"+url+"</a>";
		}
		cite+="</li>";
		$("#footnotes").append(cite);
		footnote++;
	});
});

And now, so that everyone understands exactly what this script is doing, I’ll walk you through each section of code.

$(document).ready(function() {
});

This bit of jQuery is saying “wait until the document is fully loaded (“ready”), then run the following function. This prevents our script from running while the document is only half-loaded.

$("#wrap").append("<ol id=\"footnotes\"></ol>");
footnote = 1;

The first line finds my element with an ID of “wrap” (you could use whatever element you wanted, such as the body tag), and appends (adds something to the end of) an ordered list with an ID of “footnotes.” This is where our script will stick all of our footnotes. The second line is just setting a variable, “footnote,” to a value of 1. This is the number we want our footnotes to start on.

$("q[cite],q[title],blockquote[cite],
blockquote[title]").addClass("footnote");

This line is going through our entire document and finding every q and blockquote element with either a “cite” or “title” attribute set, and giving them all a class of “footnote.”

This is a workaround to a problem I uncovered while building the script. Originally, I was just cycling through the document, grabbing all q and blockquote elements and checking for their attributes later, using jQuery’s “each” function (which we’ll see in a moment). The problem is, if you specify more than one element in an “each” function, jQuery will build an array (good) of all of your first elements first, and your second elements second, and so on (bad, in our case). Which meant that when I went through and numbered my footnotes later in the script, all the <q> tags would get numbered, and then the script would start over at the top of the page and number all my <blockquote> tags. That resulted in all my footnotes being out of order. This fixes that problem.

$(".footnote").each(function() {
});

Here’s the “each” function I mentioned previously. This line goes through the document and finds every instance of an item with a “footnote” class (which we just dynamically applied to all the appropriate elements), and then executes the contained function on every element it finds. It’s a cheap and easy “foreach” loop, basically.

$(this).append("<sup>"+footnote+"</sup>");

The first thing we do in our main function is append a footnote number to the end of the element. We put the footnote in a “sup” (superscript) tag to make it look like a footnote tag by default. You could use a different element if you so chose, and then use CSS to style it however you wish.

cite="<li>";
url=$(this).attr("cite");
title=$(this).attr("title");

I’m setting three variables here. The first, “cite,” is the foundation for our footnote at the bottom of the page. Since I’m building my footnote list using an ordered list, every element within will be wrapped with <li> tags. Next, I’m creating a variable called “url” which contains the “cite” attribute, and a variable called “title” which contains the “title” attribute. If the attribute exists on our particular quote, the variable will be set with that attribute’s contents. If the attribute isn’t set, the variable will be a Boolean “false.”

if(title && url) {
	cite+="<a href=\""+url+"\">"+title+"</a>";
} else if(title) {
	cite+=title;
} else if(url) {
	cite+="<a href=\""+url+"\">"+url+"</a>";
}

We have three “if” checks and three possible outcomes here. If both the “title” and “url” variables are set, we wrap the “title” content in an anchor tag with an href of the “url” content, and add it to the end of our “cite” variable. If just the title is set, we just output the title. And if just the url variable is set, we output the url, wrapped in an anchor tag so it’s active.

cite+="</li>";
$("#footnotes").append(cite);
footnote++;

Now we just need to wrap up our script. First, we close the list item in our cite variable, now that the rest of its content has been filled. Then we append the contents of our cite variable to the end of the “footnotes” ordered list that we created at the beginning of our script. And last but not least, we increase the number of our footnote by one, so that the next footnote will be one larger than the last.

That’s all there is to it! You can see this script in action here. Be sure to view the source code so you can see that there is no footnote list in the code… it’s being automatically generated by our script. And of course, you’ll need to include the jQuery framework at the top of your document before you can run this script (view the source on the example page for a demonstration on how to do that). And you could style your footnotes any way you please: my example page contains some rudimentary styles you can feel free to borrow.

This script could probably be made more advanced fairly easily, and I might write another article in the future on expanding this script for added functionality. If you have any suggestions on other things you’d like to see this script do, don’t hesitate to share them in the comments! I’d also love to hear if you’re planning to use this script anywhere, if you know of a better way to write my jQuery (I’m new to the framework, so it’s possible), or anything else of that nature.

10 Comments

  1. On August 13, 2008
    10:20PM

    MikeWhoBikes said:

    Great idea, I haven’t seen jQuery used like this before. I can see how this could be a huge timesaver for long academic documents.

    Just a thought: Would it be possible to have each number link to the corresponding footnote and vice versa? It would be great to be able to click a quote, have the page jump down to the relevant footnote, and then click again to return back to where I was reading. This would be a great usability improvement on long documents.

  2. On August 14, 2008
    12:04PM

    Tim Wright said:

    That’s some good stuff, very useful. Thanks

  3. Rob Glazebrook said:

    I agree, Mike: having hyperlinks in the code to jump back and forth between quotes and footnotes would be useful. And I even had it in the code at one point, but then I decided that, from a tutorial standpoint, this implementation was easier to explain. :)

    I’ll probably revamp this code at some point in the future and add that functionality then. Thanks for the comment!

  4. Jérôme Gamez said:

    Great idea and script, Rob! I liked it so much that I ported it to MooTools (which I personally prefer to jQuery) and added the “jump back and forth” feature. You can see it in action on http://whatiknowiswhatyouget.com/examples/automaticfootnotes/ – I have to admit I have stolen most of your dummy text, but I hope you forgive me :).

    Best
    - Jérôme

  5. Pradeep Mamgain said:

    Thank you very much. G8 Script.


    _pADDy_
    http://www.aniquito.com

  6. Santhos Webdesign said:

    Very nice thanks a lot for this!

  7. acms said:

    very good for legal documents, thanks for sharing

  8. CircleReader said:

    I use Simon Elvery’s plugin for WordPress, WP-Footnotes. Since WordPress also uses jQuery, you may find it useful to look at his code…

  9. Brian Holt said:

    This was a great idea. I extended it a bit and made it into an actual jQuery plugin. It’s been working on my site for a while now; I’m just now getting around to packaging it up so others might be able to use it as well.

  10. Charles Boyung said:

    Great post, this was just what I was looking for. One good change to make is to use .after instead of .append when adding your footnote number to the . This puts the number outside of the quotes that get generated by browsers when you use that element. Otherwise, love it.

11 Responses Elsewhere

  1. Автоматические сноски | Чернев.ру said:

    [...] Сайт автора скрипта(Английский) [...]

  2. Generating Automatic Website Footnotes with jQuery - Kreativuse™ - Creative Resources and Inspirations said:

    [...] Sometimes a writer likes to use footnotes in their articles for easier references for the reader. But to write it down one-by-one is a tough job. Here is an automated version of it. Read more about this method. [...]

  3. Weekly Links #14 | GrantPalin.com said:

    [...] Generating Automatic Website Footnotes with jQuery [...]

  4. jQuery-based Footnotes « AlltagsGrauen v7.0 said:

    [...] know by now there’s already some kind of implementation of this using jQuery, but this one is kinda handicapped or too short reaching for my purposes, because it [...]

  5. Using jQuery for putting links and quote cites in a footnote for print | Søren Madsens blog said:

    [...] won’t take credit for this very handy usability enhancement. Credit goes where credit is due (hat tip, Rob Glazebrook) – but we made a few changes to the script, so that it eg. now also includes links (hrefs), and we [...]

  6. What I know is what you get » Blog Archive » Automatic Footnotes with MooTools said:

    [...] have found a script to generate automatic website footnotes (with jQuery) that I liked so much that I did it the MooTools way and added some additional [...]

  7. 網站製作學習誌 » [Web] 連結分享 said:

    [...] Generating Automatic Website Footnotes with jQuery [...]

Leave a Comment