January 27, 2010

Using the J/K keys for Content Navigation

If anyone has ever been to the Boston Globe's The Big Picture or FFFFOUND! you may have used your keyboard to navigate through a page's content. The j (forward) and k (backward) keys use as navigation has started to trickle into modern sites. Even Google's Gmail uses this convention to navigate between emails.

I wanted to give it a try so I've created a sample jQuery plugin (not really all that full-featured) that offers similar functionality as The Big Picture.

The code is pretty straight forward. It simply finds all images inside the given container.

$('#image-wrapper').jkNavigation();

Keeping track of the currentImage variable was a bit tricky so if anyone has any optimizations, let me know.

Tested in Safari 4.0.4 and Firefox 3.5.7.

(function ($) {
  $.fn.extend({
    jkNavigation: function (options) {
      return this.each(function () {
        new $.JKNavigation(this, options);
      });
    },
  });

  $.JKNavigation = function (element, options) {
    var defaults = {
      // no options at the moment
    };
    this.options = $.extend({}, defaults, options || {});
    this.element = $(element);
    this.images = $('img', this.element);
    this.currentImage = null;
    this.run();
  };

  $.extend($.JKNavigation.prototype, {
    run: function () {
      self = this;

      $(window).bind('keydown', function (event) {
        var key = event.keyCode;

        switch (key) {
          case 74:
            if (self.currentImage == null) {
              self.currentImage = 0;
            } else if (!(self.currentImage == self.images.length - 1)) {
              self.currentImage++;
            }
            break;
          case 75:
            if (self.currentImage == null) {
              return;
            } else if (!(self.currentImage == 0)) {
              self.currentImage--;
            }
            break;
          default:
            return;
        }

        var img = self.images.eq(self.currentImage);
        var pos = img.offset().top;

        $('html, body').scrollTop(pos);
      });
    },
  });
})(jQuery);