Introduction
OK, so JavaScript/jQuery lightboxes are ten-a-penny. Just go to the jQuery plugin repository and take your pick! Indeed for a long time, I did just that. After all, there's no point re-inventing the wheel, is there??
However, I recently had to write my own JavaScript lightbox from scratch. So I thought now was a good opportunity to share my experiences with you, as well as the code, which you are free to use should you want or need to develop your own lightbox or maybe want to develop my lightbox further.
LiteBox
The fruits of my labours I have (unimaginatively) named 'LiteBox
', mainly to try and emphasize the fact that it makes no pretences to doing anything fancy! Also, as I am a shameless jQuery whore, I am also assuming prior experience of jQuery. If you are unfamiliar with jQuery, you can find more information here.
The Basics
LiteBox
is implemented as a jQuery plugin. The signature is as follows:
jQuery.lightbox( url, [options] )
The url
parameter is mandatory and specifies the URL of the image to be shown in the lightbox
. The options
parameter is a set of optional key/value pairs for configuring the lightbox
:
Key | Description | Default Value |
---|
title | The text to be used for the tooltip and alt attribute of the image. | The URL of the image |
showCloseButton | Whether or not to show the 'close' button on the lightbox . | True |
closeButtonPosition | The position of the 'close' button.
Can be one of either 'top-left ', 'top-right ', 'bottom-left ' or 'bottom-right '.
Ignored if showCloseButton is false . | 'top-right' |
animationSpeed | The speed of the animation.
Can be one of either 'slow ', 'medium ' or 'fast '; or the length of the animation in milliseconds. | 'medium' (= 500ms) |
Getting Into the Code
Before we delve too deeply into the JavaScript, it's helpful to have a look at the CSS:
.jquery-litebox-lightbox
{
position: absolute;
background-color: Transparent;
z-index: 1001;
margin: 0px;
padding: 0px;
border: 10px solid white;
}
.jquery-litebox-img
{
margin: 0px;
padding: 0px;
}
.jquery-litebox-close
{
height: 25px;
width: 25px;
position: absolute;
cursor: pointer;
background-image: url(images/jquery-litebox_close.png);
background-repeat: no-repeat;
z-index: 1002;
}
.jquery-litebox-shadow
{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: url(images/jquery-litebox_shadow.png);
background-repeat: repeat;
}
As is customary with jQuery plugins, the first thing we need to do is merge any user options into a settings
object:
var settings = {
title: url,
showCloseButton: true,
closeButtonPosition: 'top-right',
animationSpeed: 'medium'
};
$.extend(settings, options);
The next thing to do is create a <img>
tag for the full-sized image, and add it to the DOM. It is important that we do this early on as we need the browser to have loaded the image in order to work with its properties, such as height
and width
, etc. However, we make the image invisible so that it doesn't actually appear to the user yet:
var img = $('<img src="' + url + '" alt="' + settings.title +
'" title="' + settings.title + '" class="jquery-litebox-img" style="display: none;" />');
$('body').append(img);
Once the browser has loaded the image, then the interesting stuff can start. By hooking into the image's load
event, we can create the lightbox
and append the image to it:
var imgWidth = $(this).width();
var imgHeight = $(this).height();
$(this).detach().height('0px').width('0px');
var lightbox = $('<div class="jquery-litebox-lightbox"></div>').css
('top', $(window).scrollTop() + 100 + 'px').css('left',
($(window).width() / 2) - (imgWidth / 2) + 'px');
var shadow = $('<div class="jquery-litebox-shadow"></div>');
$('body').append(shadow);
$('body').append(lightbox);
lightbox.append($(this));
As you can see, we firstly get the height
and width
of the image. We then detach the image from the DOM and set its height
and width
to 0px
.
Next, we create the lightbox
itself. Now that we know the height
and width
of the image, we can calculate and set the position of the top-left-hand corner of the lightbox
such that it will be centered horizontally on the page and 100px
from the top of the window.
We then create the lightbox
shadow and append it to the DOM. We append the lightbox
itself to the DOM and then append the image to the lightbox
.
Now the time has come to animate our lightbox
. The animation is very simple: we simply grow the image from top-left
to bottom-right
until the image is at its full size. This is achieved using jQuery's animate()
function:
var animationTime = getAnimationTime(settings.animationSpeed);
$(this).show().animate({
width: imgWidth,
height: imgHeight
}, animationTime, function () {
if (settings.showCloseButton) {
showCloseButton(settings.closeButtonPosition);
img.mouseover(function () {
showCloseButton(settings.closeButtonPosition);
});
img.mouseout(function (e) {
hideCloseButton(e);
});
}
});
When the animation is complete, we hook into the mouseover
and mouseout
events of the image to show and hide the close button respectively. The code for showing and hiding the button is as follows:
function showCloseButton(position) {
var img = $("img.jquery-litebox-img");
var imgPositionY = img.offset().top;
var imgPositionX = img.offset().left;
var imgHeight = img.height();
var imgWidth = img.width();
if ($("div.jquery-litebox-close").length == 0) {
var close = $('<div class="jquery-litebox-close"
title="Close the lightbox." style="display: none;"></div>');
$('body').append(close);
switch (position) {
case 'top-left':
close.css('top', imgPositionY).css('left', imgPositionX);
break;
case 'top-right':
close.css('top', imgPositionY).css('left',
(imgPositionX + imgWidth) - close.width());
break;
case 'bottom-left':
close.css('top', (imgPositionY + imgHeight) -
close.height()).css('left', imgPositionX);
break;
case 'bottom-right':
close.css('top', (imgPositionY + imgHeight) -
close.height()).css('left', (imgPositionX + imgWidth) - close.width());
break;
default:
throw new Error("Buttom position must be one of either:
'top-left', 'top-right', 'bottom-left' or 'bottom-right'.");
}
close.click(function (e) {
$(this).remove();
closeLightBox();
});
close.show();
}
}
function hideCloseButton(mouseEvent) {
if (!isIn($("div.jquery-litebox-close"), mouseEvent))
$("div.jquery-litebox-close").remove();
}
function isIn(obj, mouseEvent) {
if (obj.length > 0) {
var x = mouseEvent.pageX;
var y = mouseEvent.pageY;
var posX = obj.position().left;
var posY = obj.position().top;
var objX = obj.width();
var objY = obj.height();
return x > posX && x < posX + objX && y > posY && y < posY + objY;
}
else
return false;
}
The animation time is determined by calling the getAnimationTime()
function:
function getAnimationTime(speed) {
if (typeof speed === 'string') {
switch (speed) {
case 'slow': return 1000;
case 'medium': return 500;
case 'fast': return 250;
default:
var parsedSpeed = parseInt(speed);
if (!isNaN(parsedSpeed))
return parsedSpeed;
else
throw new Error("Animation speed must be a
number or one of: 'slow', 'medium' or 'fast'.");
}
}
else if (typeof speed === 'number')
return speed;
else
throw new Error("Animation speed must be a number
or one of: 'slow', 'medium' or 'fast'.");
}
Summary
LiteBox
is a very simple, lightweight jQuery lightbox
, which can serve as an example for anyone wishing to develop their own solution; or as a base for anyone wishing to extend it further.
You can download the source code, along with a sample web page from here.
You can see a demo of LiteBox
in action here.
CodeProject