Click here to Skip to main content
Click here to Skip to main content
Technical Blog

A D.I.Y. Lightbox

, 7 Jul 2011 CPOL
Rate this:
Please Sign up or sign in to vote.
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.

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
<span class="code-none">{
 position<span class="code-none">: absolute<span class="code-none">;
 background-color<span class="code-none">: Transparent<span class="code-none">;
 z-index<span class="code-none">: 1001<span class="code-none">;
 margin<span class="code-none">: 0px<span class="code-none">;
 padding<span class="code-none">: 0px<span class="code-none">;
 border<span class="code-none">: 10px solid white<span class="code-none">;
<span class="code-none">}

.jquery-litebox-img
<span class="code-none">{
    margin<span class="code-none">: 0px<span class="code-none">;
    padding<span class="code-none">: 0px<span class="code-none">;
<span class="code-none">}

.jquery-litebox-close
<span class="code-none">{
    height<span class="code-none">: 25px<span class="code-none">;
    width<span class="code-none">: 25px<span class="code-none">;
    position<span class="code-none">: absolute<span class="code-none">;
    cursor<span class="code-none">: pointer<span class="code-none">;
    background-image<span class="code-none">: url(images/jquery-litebox_close.png)<span class="code-none">;
    background-repeat<span class="code-none">: no-repeat<span class="code-none">;
    z-index<span class="code-none">: 1002<span class="code-none">;
<span class="code-none">}

.jquery-litebox-shadow
<span class="code-none">{
 position<span class="code-none">: absolute<span class="code-none">;
 top<span class="code-none">: 0<span class="code-none">;
 left<span class="code-none">: 0<span class="code-none">;
 width<span class="code-none">: 100%<span class="code-none">;
 height<span class="code-none">: 100%<span class="code-none">;
 background-image<span class="code-none">: url(images/jquery-litebox_shadow.png)<span class="code-none">;
 background-repeat<span class="code-none">: repeat<span class="code-none">;
<span class="code-none">}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>

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.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

MBigglesworth79
Web Developer
United Kingdom United Kingdom
No Biography provided
Follow on   Twitter

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.141223.1 | Last Updated 7 Jul 2011
Article Copyright 2011 by MBigglesworth79
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid