Take the 2-minute tour ×

I'm banging my head against the wall on this because I know I've done it before. But this code won't work. Now, I know a lot of this is a mess because I'm trying to throw it together quickly (Make it work, make it right, make it fast, etc), but what about this is causing me so much pain and agony?

I have the following basic HTML:

<div class="js-gallery force js-on">
  <h5>More Images &raquo;</h5>
  <a href="http://url/to/image1.jpg"><img src="http://url/to/image_thumb1.jpg" alt=""></a>
  <a href="http://url/to/image2.jpg"><img src="http://url/to/image_thumb2.jpg" alt=""></a>
  <a href="http://url/to/image3.jpg"><img src="http://url/to/image_thumb3.jpg" alt=""></a>

And the following JS to intercept link clicks, create an object to maintain state through the mini gallery (next, previous, active, etc.), and calculate screen width/height so the image fits well. Should be SO simple:

// Set up intialized variables
var overlay = $("<div class='gallery-overlay' id='gallery-overlay'></div>").hide().appendTo("body"),
  state = {},
  galleryNext = $("<a class='gallery-next' href='#'>Next</a>"),
  galleryPrev = $("<a class='gallery-prev' href='#'>Previous</a>"),
  gallery = $(".js-gallery");


gallery.find("a").click( function (e) {
  state.gallery = $(this).parent(".js-gallery");
  thisHref = this.href;
  overlay.fadeIn( 200, function () { 
    buildGalleryOverlay( thisHref ); 
  return false;

$("#gallery-overlay").live( "click", function (e) {

$("#image-box a").live( "click", function (e) {
  var imageBox = $("#image-box");
  buildGalleryOverlay( this.href );
  return false;

function buildGalleryOverlay( clickedHref ) {
  var ww = $(window).width(),
    wh = $(window).height(),
    imageBox = $("<div class='image-box' id='image-box'></div>").appendTo(overlay).show(),
    image = $("<img src='" + clickedHref + "' />"),
    iw, oldW,
    ih, oldH,
    overWidth, overHeight,

  window.console.log( imageBox );

  if ( !state.total ) {
    state.total = 0;
    state.images = [];
    allImages = $(state.gallery).find("a");
    $.each( allImages, function (index, value) {
      state.total += 1;

  state.active = state.images.indexOf( clickedHref );
  state.next = state.images[state.active + 1];
  state.prev = state.images[state.active - 1];

  window.console.log( image );
  iw = $(image).width();
  ih = $(image).height();

  // continued...

Right here is where the problem happens, because every so often a click on an image link will return 0 and 0 for the width and height. No idea why. And when that happens, the script doesn't work (the image gets hidden if the CSS is set to width: 0, height: 0—or if I turn that off then these images are too big for the screen):

  window.console.log( iw );
  window.console.log( ih );

  overWidth = iw - ww;
  overHeight = ih - wh;

  if ( overWidth > 0 || overHeight > 0 ) {
    if ( overWidth > overHeight ) {
      // Landscape
      oldW = iw;
      iw = ww - 80;
      ih = (iw * ih) / oldW;
    else {
      // Portrait
      oldH = ih;
      ih = wh - 160;
      iw = (ih * iw) / oldH;

  galleryPrev = galleryPrev || $("<a href='##' class='gallery-prev'>Previous</a>");
  galleryNext = galleryNext || $("<a href='##' class='gallery-next'>Next</a>");

  galleryPrev.attr( "href", (state.prev || state.images[state.images.length - 1]) ).appendTo( imageBox );
  galleryNext.attr( "href", (state.next || state.images[0]) ).appendTo( imageBox );

  // Here I've turned off the CSS adjustments because iw and ih were getting 0s

  if ( iw && iw > 0 && ih && ih > 0 ) {
    image.css({width: iw + "px", height: ih + "px"});


share|improve this question
Question title might be a tad misleading -- I'm loading the image on the page and trying to calculate the height/width immediately. I'd understand if it never worked but it works 80% of the time, so that other 20% is really confusing me! –  rhodesjason Mar 2 '12 at 19:45
And you are using lightbox, i presume. you better put that up in the answer if you are. –  Anish Gupta Mar 2 '12 at 19:45
What's the point of wrapping a jQuery object in another jQuery object? image = $(...) ... $(image).width(); –  Dagg Nabbit Mar 2 '12 at 19:46
Would these be of any help? api.jquery.com/width and api.jquery.com/height –  Anish Gupta Mar 2 '12 at 19:46
add comment

2 Answers

Take a look at: http://www.javascriptkit.com/jsref/image.shtml

You can't calculate the size of an image that hasn't been loaded from the server, but you can load the image via JS using the Image() object and get the calculations you need done before actually inserting that image into the page.

share|improve this answer
add comment

Personally, I would make a PHP script using GD that grabs the dimensions of an image residing on the server and just call it via some AJAX method that returns the results to your JavaScript. Page then never loads the image, which could be beneficial in certain situations where you may need to exclude/modify the image because of it's width/height.

Just a thought.

share|improve this answer
GD tools are incredibly expensive to use though. If you load a page with 10 images in it and make 10 ajax calls to 10 PHP processes that load 10 images with GD all at once... Wait I think I can hear CPUs screaming in agony :P it's best to do calculations on images when you process them, not in realtime. Storing uploaded image data like size/filetype/etc in a database and populating it when an image is uploaded to your server through a script is a much much much better approach than using GD to read something as generic as image dimensions and spamming your server with AJAX requests. –  Brian Mar 2 '12 at 20:50
add comment

Your Answer


