Introducing ChatKeeper — a new tool from Martian Software that keeps your ChatGPT conversation history safe, searchable, and accessible forever. Try it for free!

Targetting Frames in XHTML

Update March 13, 2008

I used this technique on an older version of this website. I'm no longer using it because I think it's friendlier to let the user decide where windows should open.

Marty

This isn't so much an article as it is a tip. I'm writing this as I finish converting the Martian Software website to XHTML 1.1. The previous incarnation of this site (HTML 4.0 Transitional) relied upon the target attribute of the <a> tag to use a new frame for links outside the site, and to consistently reuse the same frame for all javadoc links. It worked great.

Once I switched to XHTML, however, I quickly found that target is no longer a built-in attribute for <a> tags. It could be done with some DTD gymnastics, but that seemed a ridiculous amount of effort just to retain some simple functionality. Then I found this article by Kevin Yank which provided a pretty clever method: mark the links you want to launch in a new window using the rel attribute, and massage the DOM with a little javascript. I won't repeat the reasoning here (it's a good article - go read it), but I think it's a great solution that, although it relies upon javascript, degrades quite gracefully.

It didn't totally fit my needs, however. I wanted to re-use frames as well rather than keep launching new windows. So I made a couple of tweaks:

It works great, and it's used everywhere on this website. The modified script is included below.

function externalLinks() {
  if (!document.getElementsByTagName) return;
  var anchors = document.getElementsByTagName("a");
  for (var i=0; i<anchors.length; i++) {
    var anchor = anchors[i];
    if (anchor.getAttribute("href") && anchor.getAttribute("rel")) {
      var rel = anchor.getAttribute("rel");
      if (rel == "external") {
        anchor.target = "_blank";
      } else if (rel.substring(0,9) == "external:") {
        anchor.target = rel.substring(9, rel.length);
      }
    }
  }
} 
window.onload = externalLinks;

Martian Software, Inc. footer logo