Improving Link Display for Print

by Aaron Gustafson

49 Reader Comments

Back to the Article
  1. 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).

    Copy & paste the code below to embed this comment.
  2. 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.

    Copy & paste the code below to embed this comment.
  3. 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.

    Copy & paste the code below to embed this comment.
  4. There is a very cool Greasemonkey user script that will do something similar for any page.
    It’s called “Annotate Links”:http://www.xs4all.nl/~jlpoutre/BoT/Javascript/AnnotateLinks/

    Copy & paste the code below to embed this comment.
  5. 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.

    <ot>Also, it seems strange that you have all your functions written to use apply. Why make things harder than you have to?</ot>

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

    Copy & paste the code below to embed this comment.
  6. 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.

    Copy & paste the code below to embed this comment.
  7. 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;
        var media = link.getAttribute(‘media’);

        if ((media) && (media == ‘print’) ) {
        link.setAttribute(‘media’,media + ‘, screen’);
        link[removed].replaceChild(link,link);
        }
      }
    }

    I suppose I really should get around to writing this up too…

    Copy & paste the code below to embed this comment.
  8. Why would users need to view the printed style? To check that we are not going to waste all the colours on their printer? :P … 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…

    Copy & paste the code below to embed this comment.
  9. 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&#8230;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.
    Copy & paste the code below to embed this comment.
  10. 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.

    Copy & paste the code below to embed this comment.
  11. 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.

    Copy & paste the code below to embed this comment.
  12. 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.

    Copy & paste the code below to embed this comment.
  13. Should be easily done with CSS ID and/or classes :-)

    Copy & paste the code below to embed this comment.
  14. 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.

    Copy & paste the code below to embed this comment.
  15. 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.

    Copy & paste the code below to embed this comment.
  16. This is just awesome. I’m going to have to implement this myself. It’s so simple, but so damn effective.

    Thanks heaps.

    Copy & paste the code below to embed this comment.
  17. 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=”[removed]…”).

    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

    Copy & paste the code below to embed this comment.
  18. I was wondering if anyone else had run into this problem.  In IE6, if you have a linked image (e.g. ), I get two superscripts and footnotes – one for the <a> tag and one for the <img> tag.  The first footnote has the URL of the <a> tag, and the second has the URL in the src attribute of the <img> tag.

    Why does this happen?  Any ideas on how to fix it?

    You can try this out for yourself by just adding a linked image to the final HTML from the article:
    http://www.alistapart.com/d/improvingprint/files/final.html

    Copy & paste the code below to embed this comment.
  19. 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.

    Copy & paste the code below to embed this comment.
  20. 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….

    Copy & paste the code below to embed this comment.
  21. 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?

    Copy & paste the code below to embed this comment.
  22. I discovered the correct link:
    http://www.cps.brockport.edu/~cpsclub/template/footnoteLinksExpanded.js

    (The links posted in comment #37 are missing the tilde before “cpsclub”.)

    Copy & paste the code below to embed this comment.
  23. Sorry about that. Glad it worked for you (I assume it works or you’d have complained when posting).

    Copy & paste the code below to embed this comment.
  24. 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!

    Copy & paste the code below to embed this comment.
  25. 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

    Copy & paste the code below to embed this comment.
  26. Another possibility would be to check the myArr array to see if it is empty before appending the <h2> and <ol>:

    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.

    Copy & paste the code below to embed this comment.
  27. I’ve just implemented this on my own site (www.fueladvance.com) and it rocks! Try printing our homepage…

    Copy & paste the code below to embed this comment.
  28. @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.

    Copy & paste the code below to embed this comment.
  29. 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

    Copy & paste the code below to embed this comment.