Improving Link Handling in Print
Issue № 203

Improving Link Display for Print

When I was nearing completion of my last article, I printed a copy of it for my wife, Kelly, to proofread. As it was an article for publication online, I had written it in HTML and printed it from the test server, taking advantage of my trusty print style sheet to make it look right.

Article Continues Below

About a page in, Kelly let out an annoyed sigh and posited “How do you expect me to read this with all of these URLs in the middle of everything?” It seemed my zeal for linkage had come into conflict with my desire to improve print usability.

What’s a developer/husband to do? Fix it, of course. And so I dedicate this article to Kelly: may she continue to proofread my articles unimpeded.

Eric Meyer’s printed page#section2

Many moons ago, Eric Meyer wrote a ground-breaking article for A List Apart, in which he offered up a little CSS2 nugget:

a:link:after,
a:visited:after {
  content: " (" attr(href) ") ";
  font-size: 90%;
}

Using this rule in a print style sheet will cause any browser that understands CSS2 (Mozilla & Netscape, at the time, and most everything but IE at the time of publication, though we are told the forthcoming IE7 will support generated content) to insert the value of an anchor’s href attribute, in-line, after the text, slightly smaller and flanked by parentheses:

A sample of generated contentent from one link in a paragraph.

This is incredibly helpful for users who print the page, as it alerts them to the destination of each link. When you have a paragraph with a lot of links (especially long ones), however, this technique hinders readability:

A sample of generated contentent from many links in a paragraph.

We can’t have that.

The plan#section3

Having spent many years in academia and publishing, I’m partial to footnotes/endnotes. They are a standard convention in print, so it seems natural to go in that direction. Following this line of thinking, our objectives would be to:

  • collect all of the URIs referenced (hrefs and citations) in a specific container within the page (after all, we probably don’t want to grab the navigation, etc.),
  • place the links (minding the duplicates) into an ordered list which can be dropped into an id-ed container of our choosing, and
  • supply each reference with the corresponding footnote number as a superscript.

Luckily, all of this is well within our grasp when we access the DOM via JavaScript.

The script#section4

Before we start scripting, we should outline detailed directions for ourselves in the code:

function footnoteLinks() {
  // get the container and target // create a heading for the footnotes 
  // create an <ol> to contain the footnotes 
  // create an array to store used links 
  // so we can check for duplicates 
  // create a variable to keep track of the number used for each   
  // link, so we have it for footnote references 
  // collect all of the elements in the specified container into an array 
  // cycle through the elements in that array,
  // looking for hrefs and citations
  // if a duplicate
  // get the corresponding number from the array of used links
  // if not a duplicate
  // build the <li> and append to the <ol>
  // store the link in the array  // increment the number variable
  // build the <sup> and append after the reference
  // append the heading and <ol> to the target
}

This provides a pretty solid foundation, so let’s get building. We’ll tackle each task separately, starting by examining the function itself. We need to pass it two variables: one for the id of container we are grabbing the URIs from (containerID) and one for the id of the target container for our footnotes (targetID):

function footnoteLinks(containerID,targetID) {

Now that we’ve added those arguments, we can quickly identify those containers in our script:

// get the container & target
var container = document.getElementById(containerID);
var target    = document.getElementById(targetID);

This will make things much simpler later on.

The heading for our content is up next. As we want it (as well as the rest of our generated markup) to show up in print only, we’ll class it “printOnly” (we’ll write the CSS rule for this later):

// create a heading for the footnotes
var h2     = document.createElement('h2');
addClass.apply(h2,['printOnly']);
var h2_txt = document.createTextNode('Links');
h2.appendChild(h2_txt);

[Note: we are applying the addClass() function from the Easy! Designs jsUtilities package to class our elements.]

Now we can create our ordered list and those variables we need to help us keep track of what’s going on:

// create an <ol> to contain the footnotes
var ol = document.createElement('ol');
addClass.apply(ol,['printOnly']);// create an array to store used links
// so we can check for duplicates
var myArr = []; // to store all the links
var thisLink;   // to store each link individually
// create a variable to keep track of the number used for each 
 // link, so we have it for footnote references
var num = 1;

Now for the heavy lifting. We need to iterate through all of the elements in the container, looking for href and cite attributes. It is good to note that in XHTML 2.0 we will be able to make anything a link and we can already put a cite attribute on almost anything, not just <figure class="quote"><blockquote>s and <q>s, so we should not restrict ourselves to only collecting anchors, block quotes and inline quotations:

// collect all of the elements in the specified container into 
// an array
var coll = container.getElementsByTagName('*');

Now we can loop through that collection, looking for href and cite attributes:

// cycle through the elements in that array, looking for hrefs 
// and citations
for (var i=0; i<coll.length; i++) {
  // check for our attributes
  if ( coll<i>.getAttribute('href') ||
    coll<i>.getAttribute('cite') ) {
  // grab the reference
    thisLink = coll<i>.getAttribute('href') ? coll<i>.href 
    : coll<i>.cite;

That looks good so far. Now we need to create our superscript:

 // build the <sup> and append after the reference
  var note = document.createElement('sup');
  addClass.apply(note,['printOnly']);

We’re going to assume each URI reference will be unique for now, revisiting the script later to check for duplicates:

 var note_txt = document.createTextNode(num);
  note.appendChild(note_txt);

We’re also going to assume we are dealing with anything but blockquoted text for now, and we’ll append the reference inline before the referencing element’s next sibling:

 coll<i>.parentNode.insertBefore(note, coll<i>.nextSibling);

We create a list item to contain the URI and then push that URI to the waiting array (so we can use it to reference duplicates):

 // build the <li> and append to the <ol>
    var li     = document.createElement('li');
    var li_txt = document.createTextNode(thisLink);
    li.appendChild(li_txt);
    ol.appendChild(li);
    // store the link in the array
    myArr.push(thisLink);

[Note: not all browsers natively support the push method, but you can help such unfortunate browsers deal by writing a script to define the method for them. It is also available in the jsUtilities package.]

Now we increment our number to prepare for the next reference and close the loop:

   // increment the number variable
    num++;
  }

Finally, we append our heading and list to the target:

 target.appendChild(h2);
  target.appendChild(ol);
}

We have a little tidying up to do before we wrap the script. First of all, we need to handle duplicate URI references. We accomplish this by looking through that array (myArr) we created for keeping track of our used URIs. We can do that with the JavaScript port of PHP’s inArray function (also available in the jsUtilities package). inArray looks for a value (needle) in whatever array (haystack) we apply it to and returns “true” (with the index value) if found and “false” if not found. We use it when we are looping through the collection:

for (var i=0; i<coll.length; i++) {
  if ( coll<i>.getAttribute('href') || 
    coll<i>.getAttribute('cite') ) { 
    thisLink = coll<i>.getAttribute('href') ? coll<i>.href 
      : coll<i>.cite;
    var note = document.createElement('sup');
    addClass.apply(note,['printOnly']);
    var note_txt;
    var j = inArray.apply(myArr,[thisLink]);
    if ( j || j===0 ) { // if a duplicate
      // get the corresponding number from the array of 
      // used links
      note_txt = document.createTextNode(j+1);
    } else { // if not a duplicate
      // build the <li> and append to the <ol>
      var li     = document.createElement('li');
      var li_txt = document.createTextNode(thisLink);
      li.appendChild(li_txt);
      ol.appendChild(li);
      // store the link in the array
      myArr.push(thisLink);
      note_txt = document.createTextNode(num);
      // increment the number variable
      num++;
      }
    note.appendChild(note_txt);
    …
  }
}

In the snippet above, we are looking to see if thisLink is found in myArr and then handling the superscript accordingly. If thisLink is found (j is “true”), we make the superscript j+1 (as array indexing starts at 0 and ordered lists start at 1) and we’re done. If thisLink is not found (j is “false”), we need to create the list item for the reference, append it to the <ol>, push thisLink to myArr, and create our superscript reference (incrementing num afterwards). It is important to note that, as inArray returns the array index, the value of j could be 0 if it is the first item in the array. JavaScript will interpret this as false if we were to use the “is equal to” operator (j==0), so we use the “is identical to” operator (j===0) to be able to pick up duplication of the first URI reference in a given page.

The next step in tidying-up involves adding our reference in block-level elements. If you are making a block-level quote of some sort, to be truly semantic, it needs to be in a <figure class="quote"<>blockquote<. Your <figure class="quote"<>blockquote> could contain any type of block-level element, most commonly paragraphs (<p>) and lists (<ul>, <ol>, <dl>). Being that we would want to have our reference superscript appear at the end of the last line of text (to maintain common typographic style), we need to find the last child of the <figure class="quote"<>blockquote> which is a text-containing block-level element. We can accomplish this with the function lastChildContainingText (you guessed it, in jsUtilities):

function footnoteLinks(containerID,targetID) {
  …
  if (coll<i>.tagName.toLowerCase() == 'blockquote') {
    var lastChild = lastChildContainingText.apply(coll<i>);
    lastChild.appendChild(note);
  } else {
    coll<i>.parentNode.insertBefore(note, coll<i>.nextSibling);
  }
  …
}

Finally, we can round out our script by making it degrade gracefully in browsers that don’t support the methods we use in this function…

function footnoteLinks(containerID,targetID) {
  if (!document.getElementById ||
      !document.getElementsByTagName ||
      !document.createElement) return false;
  …
}

…and in pages that contain neither our target nor container elements:

function footnoteLinks(containerID,targetID) {
  if (!document.getElementById ||
      !document.getElementsByTagName ||
      !document.createElement) return false;
  if (!document.getElementById(containerID) ||
      !document.getElementById(targetID)) return false;
  …
}

Now, we simply set the function to run on page load.

window.onload = function() {
  footnoteLinks('container','container');
}

Then we create a style for .printOnly in our screen style sheet…

.printOnly {
  display: none;
}

…and you can see the finished product.

Contingencies#section5

This process, of course, assumes JavaScript is available for use, but what if it isn’t? To take this into account, we can keep Eric’s content generation CSS intact, using that as a fall-back to our script, and removing it when the script runs successfully.

This is accomplished by retaining the original CSS declarations for generating the href content and then, when the script runs, we class-ify <html> as “noted.” We then add a rule to our print style sheet to disable the content generation when the links in question are descendants of html.noted:

html.noted a:link:after,
html.noted a:visited:after {
  content: "";
}

Wrapping up#section6

So there you have it, a nice, clean, printable document with all links and citations collected into footnotes. Use it, enjoy it, and improve on it. For example, you could add in the ability to ignore particular links classed as “ignore.” Get creative and let us know what you come up with.

You can download the latest compressed version of footnoteLinks from its homepage or download the working files for this article from this site. All of the JavaScript prototypes used in this article are contained in jsUtilities 2.1, which is available as a compressed download from its homepage.

49 Reader Comments

  1. Thank you for your hard work, this script will certainly make it easier for users to archive sites.

  2. I did something similar over a year ago (wrote to A List Apart back then to recommend it as an article – twice – but got no response). It really is a highly useful technique, and this is a great overview of it.

    My solution added a couple of extra things – firstly I had an ‘exclude’ list – of classes and id’s – any links inside them got ignored (this allowed people to print my blog articles, but not have navigation links shown up). I also created a screen-view with the print style sheet so you didn’t need to use print preview (I just used some simple javascript to extract the print style sheet and rerender the page with it). I never did do a proper writeup, and now someone’s beaten me to it 🙂

  3. The techniques on ALA never cease to amaze me with their ingenuity and this one is no exception. This article has educated me twofold – firstly, by showing me that you can actually display links in a print stylesheet (something I was never aware of) and secondly by showing that you can, with a bit of simple and logical scripting, format the links into a readable footnoted format. Excellent stuff.

  4. Great article. Kudos to everyone at ALA 😀

    In Sam Newman’s post (3) he mentions providing a screen-view of the print style – something like ‘view printable version’. I have always wondered if we should or should not be providing this functionality to users. What does everyone think?

    Why would users need to view the printed style? To check that we are not going to waste all the colours on their printer? 😛 … Is knowledge of printed styles so fleeting in web users that they need to see for sure they are printing a stripped-down ready-for-print version?

    Love to hear what people think about this. Maybe there is already an article on it over at useit.com

  5. Thank you! Thank you! Thank you!

    This lovely little snippet of JavaScript is definitley one I will use repeatedly! I thought the article was very well written.

    As for Alex’s question (5) I think a print preview would be a good option just simply because of the varying paper sizes and margins in spme printers. I have in the oast had to modify my margins prior to printing to allow me to get everything in the articles without really breaking up the flow and outline.

    If you offer the visitor a print preview they can see what it will look like at their default printer settings so that they can make any adjustments needed.

    Again though I can see this script having a very long and useful life in the archive of useful JavaScripts I have been puttin together. Thanks again for all your hard work!

  6. I must say I really love this idea. The original method (going to print) was pretty clever, but it did render quite… ugly 🙂 This is beautiful though! Well done!

  7. Really simple technique, but such a brilliant idea! congratulations!

    I agree with Sam about implementing an exclude list, and I suggest that not only menu links should be excluded but even all the internal links, I think only externals and files (PDF, DOC etc.) links should be printed…

    For example in a presentation page on a commercial site often happens that a link to a page already in the menu is recalled into the text body: “And don’t forget to visit our customers area to find out offers & discounts”.

    Why should you report this link? To reach main areas of the site you just need the main domain.

    This technique is awesome if used as “Bibliography” and link/cite your sources, but pay attention not to link “everything”.

    Bye

  8. Well assuming you’re using relative links for everything on the site, why not just check if the href commences with ‘http’ ?

    This is a cool technique, but i’m not 100% convinced. I mean if someone really wanted to check out a link, then to go to the original article and select it is only one extra page load + a mouse click.

    If they wanted to check out more than one then they would probably do that anyway to save typing.

  9. Hi! A great article. But wouldn’t
    window.onload = function() {
    footnoteLinks(‘container’,’container’);
    }
    make all previous onload-added functions be erased? I would have suggested Scott Andrew’s addEvent function, but I recently read about some flaws of that method at http://www.quirksmode.org/blog/archives/2005/08/addevent_consid.html – have a look at http://www.quirksmode.org/blog/archives/2005/09/addevent_recodi.html for some alternate ways instead.

    On the “Print Preview” matter… I wonder if that wouldn’t be “lying to the visitor” in a way: maybe she has made some customisations in the browser that makes the prints different; for example told the browser to exclude background pictures, colors or whatever on print-out. Would a “Print Preview” be able to adapt to that?

  10. _ “…told the browser to exclude background pictures, colors or whatever on print-out. Would a “Print Preview”? be able to adapt to that?”_

    The typical modern browser comes with a Print Preview that does most of what you say. Why duplicate that?

    I would like to see the article’s effect working _on the screen version_ though. It’s just to good to hide! However, I’m not digging the superscripted numbers. What happens if they follow text that is already superscripted? Ie: the squared part at the end of Einstein’s famous formula.

    I’ve seen print use square brackets around numbers after important words, so I would prefer that. Eg:

    Visit Meyerweb.com[1]

    The problem there lies in that the HTML list at the end uses numbers and periods, which doesn’t match the above format. Perhaps generated content could come to the rescue?

  11. This is seriously great. But what if your document already has footnotes? Maybe an alternate numbering system, such as the links as a,b,c and your regular footnotes as 1,2,3?

    Or perhaps a more complex solution that will automatically renumber your existing footnotes and correctly intersperse the links?

  12. (to Pär Axelsson): you can call as many functions one after another, as you want, if you do it this way:
    window.onload = function() {
    functionOne();
    functionTwo();
    functionThree();
    }
    make sure, there is no “onload” call from the “body” tag, though.

  13. We did this on our site about 8 months ago and have found it to be very useful. In addition to not having footnotes for navigation links, we also added some code to check if the text of the link was the url itself. If the url was already displayed, then there’s no need to have a footnote.

    Minor bug: When you cut and paste from a page using this script, the footnotes carry over, even though they didn’t show up on the screen version of the page. Haven’t figured out a workaround for this (if there is one). Any thoughts?

  14. The following code can be used to replace the duplicate-checking part of the code and avoid the use of a couple of the jsUtilities functions, including inArray, which I imagine isn’t nearly as efficient for large lists as associative arras are. Plus you can avoid that confusing bit with the === operator.

    if (myArr[thisLink]) { // if a duplicate
    // get the corresponding number from
    // the array of used links
    note_txt = document.createTextNode(myArr[thisLink]);
    } else { // if not a duplicate
    var li = document.createElement(‘li’);
    var li_txt = document.createTextNode(thisLink);
    li.appendChild(li_txt);
    ol.appendChild(li);
    myArr[thisLink] = num;
    note_txt = document.createTextNode(num);
    num++;
    }

  15. Nice to see a truly useful article at ALA for a change (i.e. not so cutting edge that we can apply it in our day-to-day work).

    I’d love to see a follow up that incorporates some of the great suggestions that have been made in the comments.

  16. Perhaps I should have explicitly stated so in the article, but I *do not* recommend using the simple onload function I used in the sample files to run the script. I *do* recommend using some method of onload handling (of which there are numerous methods available).

  17. While I was looking over the library, I noticed that the regular expression used to remove a class doesn’t take into account that the class name passed in might be part of another class name. For example, if an element has the classes “mycar car”, and you want to remove the car class, it would result in the classes being named “my car” instead of just “mycar”. The fix that I can see would be to change \s? to \b in the regular expression.

  18. This seems to be cool to me, but I am very tired and all that code, while neccessary, currently makes my brainy meats hurt. I understand what it does, and I understand the commented psuedo code near the top of the article, but the code itself melted into an impossible to understand goop right before my eyes. My problem, not yours.

    I say all this to cover my butt in case this question is totally stupid due to my current limited understanding of the code. What if you want to index links from multiple site areas in this way? For example, maybe there’s an article, a primary navigation menu with links within the current site, and a seccondary menu with external links to related articles. You want to exclude the nav section but include the other two.

    Or what about ways to exlude certain areas? What if the ID containing the article or whatever you want to be indexed contains other children that you don’t want to be indexed, ads or some such?

    I know the scripts could be edited (by someone more compitent or at least less sleep deprived than myself) to allow for these sorts of special cases. But how extensible is the script as currently written?

    I know these are special cases well beyond the scope you had in mind for this article, which I freely admit is great and don’t mean to knit pick.

    And this quasi real time comment preview widget is super cool. Someone should write an article about that.

  19. I really hate being the troll, but the jsUtilities library you reference is pretty dangerous stuff. You’ve extended _Object_ which will effectively break anyone who tries to use _for…in_ in their code.

    Also, it seems strange that you have all your functions written to use _apply_. Why make things harder than you have to?

    How ’bout making the unobtrusive JavaScript a bit more unobtrusive?

  20. The reason I didn’t simply filter out relative links (which for many sites would be good enough) is because I had a very good idea about what it was people we’re interested in – the body of the article. Back then I was a bit more disorganised (crufty URLs – ugh!) and would frequently use a fixture of relative and absolute URLs. I think I’ve fixed most of them up now, but even so some of my navigation elements use absolute links (for example my del.icio.us links).

    I can’t remember the exact reason why I showed a print view in a new window rather than relying on print preview, but think it came down to be being frustrated by how slow some of the print previews in various browsers were. I also intensly dislike a print link automatically printing something without being able to see it, and hadn’t worked out how to trigger a print preview. As I already had all the cross-browser DOM walking sorted, finding any print stylesheets and adding screen was a breeze.

  21. I dug out the code snippet I used to make my print stylesheets visible. It’s kind of taken out of context – my print reloaded the page using a query string requesting the print view, which in turn changed the stylesheet link:

    /*
    * Makes all ‘print’ stylesheets ‘screen’ stylesheets as well so you can see how it will print…
    * TODO: match on ‘print’ assumes a single media type – need to support a list of media types (with indexof?)
    */
    function showPrintStylesheets() {
    var links = document.getElementsByTagName(‘link’);

    for (i = 0; i < links.length; i++) { var link = links[i]; var media = link.getAttribute('media'); if ((media) && (media == 'print') ) { link.setAttribute('media',media + ', screen'); link.parentNode.replaceChild(link,link); } } } I suppose I really should get around to writing this up too...

  22. bq. Why would users need to view the printed style? To check that we are not going to waste all the colours on their printer? 😛 … Is knowledge of printed styles so fleeting in web users that they need to see for sure they are printing a stripped-down ready-for-print version?

    Given the number of websites that haven’t got the hang of print stylesheets, and allow sidebars, ad banners and columns wider than a page to be printed, is it any wonder that users are reluctant to just press ‘Print’?

    I’ve had a print.css on my website for a long time, but I still get the occasional user suggest that I add a Print-friendly format for each page so that they don’t have to print the blue background – they obviously haven’t found the Print Preview button (and yes, most of them are using IE6 – if they only had v5 I could sympathise).

    Those users may be a minority. It may be that most people (i) trust me not to waste their colour ink, (ii) don’t care if I waste their colour ink, or (iii) have found the Preview button. I don’t know, and I don’t know how to find out…

  23. I just wanted to let everyone know that I will be incorporating a lot of the great ideas/improvements suggested here into the latest revisions of my jsUtilities library and the footnoteLinks script itself (giving credit where it is due, of course). It will probably be a few days before I can get it all together and put it up on “my site”:http://www.easy-designs.net but I wanted to let you all know that your ideas are great and are not being ignored. If you made a suggestion and would like credit, please email me (aaron [at] easy [dash] designs [dot] net) your name and website (if it isn’t complete here in the discussion) and if your fix makes it in, I will add your info to the comments.

    A few quick responses:
    * To answer “Derek’s concern”:http://www.alistapart.com/comments/improvingprint?page=3#23 about excluding certain sections, currently that is not supported, but a @class@ of “ignore” on any element will effectively exclude it. Also, the script already has the ability to perform its duties on a uniquely identified section of your choosing and (based on my experience) I have not found a need for more. I keep my most important content (which is where I’d want the links pulled from) in a @div@ with an @id@ of “content.”

    * As for “David’s concern”:http://www.alistapart.com/comments/improvingprint?page=3#25 about my redefining of @Object@, I will certainly look into the issue and see if there are remedies (I don’t often use @for…in@ loops in JavaScript). Also, my use of @apply@ was somewhat annoying, I know, but was necessary to accomodate Internet Explorer, which does not currently allow extension of @Element@, @Array@, etc. which was my preference. I have requested that this be remedied in the forthcoming version 7, but we’ll see if that actually happens.

  24. I’m probably more sleep deprived now than I was while writing my original message. I appologize in advance for any incoherance on my part.

    As long as there’s an effective way to exclude an area, such as class=”ignore”, I can’t really think of any situation that can’t be handled. It may not be the most efficient possible way, especially if you end up having to exlude 3 elements in order to include 2 children of some parent element, but it’d work. And I freeley admit any situation like this would be pretty rare. So that answers my original concerns quite nicely.

    Also, the link to your site that’s attached to your name is missing the : in http:// so something somewhere is being helpful and adding http:// in front of it, which kills the link.

  25. Great idea, great article. I just implemented the idea in my gaming fansite and printed pages look better than ever. I was using Eric’s idea previously but there were often too many links near each other, and the result was quit scary. But now it all looks great, thank you again 🙂
    I went a very little step further and replaced:
    document.createTextNode(‘Links’);
    with document.createTextNode(‘Link index – ‘+self.location); and added a page-break-before: always; to the styles of the “Links” container.
    The final result: the links now come in the last printed page (the user might not want to print it out) and the title says what page the links are from so that the page doesn’t get lost.

  26. Is there a way to ignore all links inside blocks such as wrapping paragraphs and divs? I don’t have any javascript skills…

    Thank for your artice! I’m already using it.

  27. Interesting but there is one little flaw. Currently the script appends a class of @noted@ to the @html@ element (gasp !). Class is not a valid attribute for @html@ in any of the official DTD (see the “html 401 rec”:http://www.w3.org/TR/html401/struct/global.html#edef-HTML for a starter). In practice, this is not so important, all current modern browsers actually support it (that is, recognize the @html.noted@ selector). But still, it would be better to append said class to the @body@ element.

  28. If I apply this to a page that doesn’t have any links (and as I’m including the footnoteLinks.js file in my header, I can’t *not* include it), I get an empty section with the heading “Links” at the bottom. How can I prevent the “Links” section from appearing? Now, the page I’m creating does have links, but they’re all marked with “ignore” because they’re footnote superscripts that point to named anchors within the page.

  29. I would like to say that this is a great idea. I have expanded on this script greatly. Essentially, my changes included the dropping of the jsUtilities package (it altered Object, which from my understanding is VERY unsafe). Part of this was achieved by simply making the modifications that Brian Hardy suggested in his post and part from my own version of addClass. I expanded upon the ability to ignore certain sections. Now you can label an element to be ignored and its descendants will also be ignored.

    Also, I strip off “mailto:”‘s, and ignore any code that has an href of simply “#” (usually used as a handler for JavaScript) and links to JavaScript code (href=”javascript:…”).

    Another change is that the h2 and the ol elements are only attached if there are any links found on the page.

    Finally, the code also ignore links where the text of a link is the link itself.

    You can see an example of my code by doing a print preview against: http://www.cps.brockport.edu/~cpsclub/ (note that the e-mail address isn’t printed). The code is in compact form similar to the code in the article. A more readable version can be seen at http://www.cps.brockport.edu/~cpsclub/template/footnoteLinksExpanded.js

  30. Yes, this is a problem. Mozilla will also double the superscripts, but it won’t add a supercript for the image. I’ll look into it and see if I can fix this.

  31. Ansel: I modified my version heavily from the authors code. Mine no longer has this problem. I solved it by walking the DOM with a recursive function, rather than just grabbing every single element.

    If anyone knows anything about Memory leaks, can you please review the expanded version of the code. I’m not well versed in this (I have been reading all of the recent QuirksBlog entries on this subject) and not sure if I’ve worked around them. I think so….

  32. Brian, thanks for taking a look at it. However, the links in your previous comment (#37) don’t work (403 Forbidden). Is that page not accessible outside your university?

  33. Sorry about that. Glad it worked for you (I assume it works or you’d have complained when posting).

  34. I was just checking through the comments again to see how the discussion has progressed and it looks like you all have been very busy kicking the tires and finding bugs. I love all of the energy around this script and am very happy this has made so many of you smile. In the coming weeks I will be looking over the enhancements you all have put together and will look to roll them into a revised version I have planned.

    Thanks again for all of your feedback!

  35. This is so great! I use it on my own website, if you want to check.

    I only changed one thing: when there is no link at all, I find it disturbing to have a “links” title with no content, so I have just added a test for num > 1 before actually adding the content.

    HTH

  36. Another possibility would be to check the _myArr_ array to see if it is empty before appending the

    and

      :

      if (myArr.length > 0) {
      // append the heading and ordered list to the target
      target.appendChild(h2);
      target.appendChild(ol);
      }

      Just another way of preventing “Links” from showing up in case there are no links on the page or you have all of them in the _ignore_ class.

  37. @Brian LePore: I’ve seen you’ve made a lot of alterations, but how do you implement them? Do you have some description?

    What I was missing in the original script was not having the ability to skip elements (e.g. a menu). Even if it is set to display:none it will not print but the links are added to the list anyway. This could be solved bij adding ignore to an element (which is not possible right now) or by ignoring all elements that are not dispayed all together.
    The class ignore did not seem to work bij the way but that is probably my bad implementation.

    Another thing is that IE treats images as a link too.

    But the technique is great and offers a great result for the end user.

  38. Hi,

    The author’s technique is pretty slick. However, it wasn’t *quite* was I was searching for–hopefully someone here knows the answer. Is there a way to have a larger document that has lots of anchor links print just the page number they’ll appear on? So if you’re printing something that looks like this:

    Additional Considerations

    …it would appear in a print version as:

    Additional Considerations (p. 17)

    This ability would really help for a document I’m currently working on.

    Thanks,
    Kev

Got something to say?

We have turned off comments, but you can see what folks had to say before we did so.

More from ALA

I am a creative.

A List Apart founder and web design OG Zeldman ponders the moments of inspiration, the hours of plodding, and the ultimate mystery at the heart of a creative career.
Career