Generating Automatic Website Footnotes with jQuery

Published August 13, 2008 by CSS Newbies.

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.

29 Responses

  1. MikeWhoBikes (reply)

    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. Pingback: Автоматические сноски | Чернев.ру

  3. Rob Glazebrook (Author) (reply)

    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. Pingback: Generating Automatic Website Footnotes with jQuery | Aniquito.COM

  5. Pingback: Creando notas al pie con jQuery | aNieto2K

  6. Pingback: Generating Automatic Website Footnotes with jQuery - Kreativuse™ - Creative Resources and Inspirations

  7. Pingback: Weekly Links #14 | GrantPalin.com

  8. Pingback: Fatih Hayrioğlu'nun not defteri » 18 Ağustos 2008 web’den seçme haberler » Firefox, CSS3, tanımı, Bağlantı, SmasingMagazine, yapılmış, güzel, seçmiş, Amazon, sonuç

  9. Pingback: jQuery-based Footnotes « AlltagsGrauen v7.0

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

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

  12. Brian Holt (reply)

    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.

  13. Charles Boyung (reply)

    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.

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

  15. Pingback: Saint John Web Design | Informative Computer Solutions » Blog Archive » How To Emulate a Foreach Loop in JavaScript

  16. david (reply)

    hi just wondering if there was a want to run this only when the page is being printed? as i would like to produce somthing that lists all the urls on a page as footnotes when a page is printed

  17. Seo Services (reply)

    Do you mind if I quote a couple of your posts as long as
    I provide credit and sources back to your site? My blog is in the exact
    same area of interest as yours and my users would truly benefit from a lot of
    the information you provide here. Please let me know if this ok
    with you. Thanks!

  18. comment-229142 (reply)

    Hi! Thiѕ is my irst visit to youyr bloց! We are a team of volunteerѕ aand
    starting a new initiative in a cοmmmunity in the same niche.
    Your Ьlog provided us beneficial inbformation to work on.
    You have done a еxtraordinary job!

  19. Priceline (reply)

    Spot on with this write-up, I honestly believe that
    this site needs a lot more attention. I’ll probably be back again to read more,
    thanks for the information!

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>