Tuesday, November 11, 2008

Gotcha Of The Day - URL Fragment Not Jumping To Right Page Position

Since basically forever, a URL can have fragment at the end of it, and the browser jump to that location on the page.

For example, suppose you have a file named book.html and it looks like:


  <h2><a name='chap1' id='chap1'>Chapter 1</a></h2>

  <p>It was a dark and stormy night. ...</p>
  ...

  <h2><a name='chap2' id='chap2'>Chapter 2</a></h2>
  <p>It was also chilly out. ...</p>
  ...

You can visit the following urls:

  • book.html - View the top of the page
  • book.html#chap1 - View the page, but jump to where chapter 1 begins.
  • book.html#chap2 - View the page, but jump to where chapter 2 begins.

Nothing exotic here. Like I said, this is just supposed to work.

Yet, today, it wasn't working. For some strange reason, if I hit a url, say:

  http://www.somehost.com/article/3848#photos

The browser wouldn't open up at the photos section. Oddly, it didn't open up at the to of the page either.

This was such a stumper because this fragment behavior is Just Supposed To Work. And it's been around long enough that a modern browser should have no problem with it.

After some experimentation with the page I finally realized what's going on. My page had the following shape:

  Lorem ipsum dolor sit amet,
  consectetuer adipiscing
  elit. Morbi tempor ornare
  eros. Nunc libero. Etiam
  ipsum. 

  <a name='photos' id='photos'></a>
  <h2>Check out these neat photos</h2>

  <script type='text/javascript'>
   // Code to pull in photos
  </script>

  Lorem ipsum dolor sit amet,
  consectetuer adipiscing
  elit. Morbi tempor ornare
  eros. Nunc libero. Etiam
  ipsum. 

What was going on was that my page was loading, the browser was jumping to the right spot on the page, and then my JavaScript finished executing. The JavaScript inserted content on the page, but the browser had already positioned itself, so it couldn't take into account the JavaScript content.

The solution turned out to be quite clean. I essentially reimplemented the URL fragment behavior in JavaScript. This sounds harder than it is. My JavaScript essentially turned into:

  // make sure to import the prototype
  // library.

  //
  // code that inserts content on the page
  //

  // location.hash is automatically set to the URL fragment value
  if(location.hash == '#photos') [
    // find the node that we marked with , use the
    // prototype function to scroll to it.
    $('photos').scrollTo();
  }

I updated the JavaScript and my page jumping was back to working. This was an excellent example of a bug that couldn't happen (URL fragments not working? Impossible, the feature's been around forever, blah, blah, blah) and yet it was happening and it was a perfectly clean fix. I love debugging.

No comments:

Post a Comment