April 30, 2009

I had an issue with an application I was writing recently that positions a lightbox based on the height and with of the image inside it. I was using Javascript to get the height and width of the image, then adjust the CSS on the lightbox accordingly before displaying it. However, Internet Explorer kept returning 0 for the height and width image, causing the lightbox to display improperly.

The Problem:
Part of the application I was writing involved displaying a table with a list of image information. When a row of the table was clicked, the image itself is displayed in a lightbox positioned in the center of the screen based on the height and width of the image. I was using jQuery and the jqModal plugin to do this. I set the click event of the table row to change the ‘src’ attribute on the image tag inside the lightbox, and binded a load event to the image tag inside the lightbox that repositioned the lightbox then displayed it. That way, I was sure that the code to grab the dimensions of the image wouldn’t execute until the image was loaded. At least, that’s what I thought. For some reason, Internet Explorer was not getting the dimensions of the image, causing the upper-left corner of the lightbox to always be in the middle of the screen, despite the size of the image.

I discovered that the source of the problem was that because the lightbox was set to “display: none” when the src attribute was changed, the image wasn’t actually being loaded despite triggering the load event. Internet Explorer does not load images unless they are actually being displayed. Because of this, I kept getting 0 as the height and width of the image.

The Solution:
It turns out that the images will load properly if the containing element is set to “visibility: hidden”. However, since jQuery and the plugin I was using hides elements by setting them to “display: none” by default, I merely implemented a workaround for IE which looks something like this:

if ( navigator.appName == "Microsoft Internet Explorer" ) {

$('#lightbox-image-container').css('visibility', 'hidden');

$('#lightbox-image-container').css('display', 'block');

}

var image = document.getElementById("lightbox-image");

var imgWidth = image.width;

var imgHeight = image.height;

if ( navigator.appname == "Microsoft Internet Explorer" ) {

$('#lightbox-image-container').css('display', 'none');

$('#lightbox-image-container').css('visibility', 'visible');

}

Note I used document.getElememtById to reference the image rather than using the jQuery width and height methods because the former is more compatible cross-browser.