Just One Of Those Things You Need To Understand About JavaScript

Ever since I've published the article Dynamic Page / Replacing Content, I've gotten quite a few emails that come in from people who are trying to use it in conjunction with some other JavaScript stuff and having trouble. Most of the time, it's some kind of lightbox effect. One of their pages has a bunch of thumbnails on it, and when they load that page in, the lightbox effect doesn't work.

The problem is that when the thumbnails are loaded onto the page (via Ajax, i.e. jQuery's .load() function) they do not have any events bound to them.

/* Your lightbox plugin */
$("photos a").ceebox();  

/* Basics of Ajax */
$("nav a").click(function(e) {
    $("#main-content").load(this.href);  /* Thumbnails loaded from here */

The way that the lightbox plugin (probably) works is that it binds click events to the elements you passed in that selector (the thumbnails) when the page loads, and those click events do the lightbox action. Since the newly loaded thumbnails have no click event, the lightbox action does't work.

One way to fix it is to call the lightbox plugin after the content loads, in the callback function of the load function:

$("photos a").ceebox();  

$("nav a").click(function(e) {
    $("#main-content").load(this.href, function() {

              /* Callback function */
              $("photos a").ceebox();  /* Call this again */


A little repetitive, but that'll do the trick.

A Better Way with Delegate

While this is "just how JavaScript works" it's a known pain in the butt. Since jQuery is a library that exists to ease pains like this, of course it has a better way. That way is the .delegate() function, where instead of binding events to the individual elements, you bind an event to an element higher up the DOM tree, which isn't likely to be replaced via Ajax, which watches for those clicks.

This relies on something called event bubbling, which is a neat and important concept in JavaScript (really: the DOM model). If you click on a thumbnail, it will trigger a click event on that element, then a click event on it's parent element, and a click event on it's parent's parent element, all the way up to the root element. Because of this, we can watch for clicks on deeper-down elements from higher-up elements.

Unfortunately with our lightbox example, you would have to alter the plugin itself to get it to use delegate instead of binding directly to the elements. Definitely do-able but trickier, since you probably aren't as intimately familiar with that plugin's code as you are your own.

Listen to Remy Sharp

As this article was drafting, Remy Sharp put out a video screencast about this exact topic. He's way better at explaining it than me, so please go watch that.

Designing For A Lightbox

The 37 Signals Blog, Signal vs. Noise, has a post about a month ago with an interesting observation:
"Designing for the iPhone is like a hybrid of print and web design."

Their point was with the iPhone, you know the exact size of the screen, you know the exact browser, you know how fonts will look in that browser, you know what the screen is like and all the capabilities. That is so very different from web design, which is rife with uncertainties. In fact, much of web design is coding your way around uncertainties and playing to lowest common denominators.

The big one is resolution, knowing the exact size of what you are designing for. When else do you know that juicy bit of information? When you are designing for a Lightbox. You know, one of those fancy little bits of CSS and Javascript that grey out your whole page except a smaller box that often displays a photo or login screen or other important information. Kind of like a non-pop-up pop-up. Many lightboxes, like this one, use a fixed width and height.

You can take those dimensions and use them to your full advantage. Such as:

  • Design a cool grungy border (don't have to worry about expandability!)
  • Browse around stock.xchng and find a cool background image
  • Design images for the corners and not worry about fancy coding to get them in the right place
  • Open a new Adobe Photoshop document with those dimensions and start designing free of any thoughts of constraint