Accounting for Bad Links

Saturday, January 20, 2007, at 03:24PM

By Eric Richardson

Over on blogdowntown (as well as here) I use a little bit of Javascript to allow longer posts to start out collapsed, but give the user the ability to expand the body in place as desired. It's old code, from well before I knew anything of AJAX.

When a post is expanded or collapsed, an anchor name is added to the end of the URL, using the post ID as a key. This lets the browser scroll to the appropriate spot so that the post that was clicked is the one visible. So if the user clicks to expand post '2475,' the end of the URL will now read '/#2475.'

Simple enough.

Occasionally, though, someone links to that URL instead of using the permanent link for the post (which, using this example, would be '/blog/2475'). That works fine while while the post is on the front page, but after a few more posts go up that content is no longer anywhere to be found.

Thursday LA Observed linked to a post using the # syntax. In light of that, I was a little cautious about when I let the linked post fall out of the first five. Today, though, I had something new ready to go and needed a solution.

What I did was add a little Javascript to the main page for blogdowntown that checks for # syntax in the browser location. If it sees a #id, but doesn't see that id in the page, it loads the post and sticks it after the five posts that would normally be there. It then tells the browser to scroll down to the newly loaded content.

And best of all, it was easy. Javascript after the jump...

First I added a blank div at the end of the blog div (to allow my normal CSS to work). I called it blogxtra. Then I set up a special template that would load a blog post and put no extra HTML around it (other than just that for a normal post). Finally I added this Javascript to the bottom of the template for the main page:

var s = window.location.hash;

if ( s ) {
  s = s.slice(1)

  if (!$('p'+s)) {
    // need to get it
    var r = new Ajax.Updater(
      'blogxtra',
      '/blog/raw/'+s,
      { onComplete : function() { Element.scrollTo('blogxtra'); } }
    )
  } else {
    // we're cool
  }
}

It first checks window.location.hash to see if there's anything there. If so, it checks to see if there's a div present with that id (in my HTML I use p_ID_ as the div id for a post). If not it uses Ajax.Updater from Prototype to load the post and stick it into that blogxtra div. Finally it sends the browser scrolling down to that div.

It seems pretty smooth, and allows me to not worry about content getting linked wrong and the reference breaking as I add new content. It doesn't really do much error checking, but that doesn't particularly bother me. I don't mind dumb links breaking, just accidentally incorrect ones.