Accéder au contenu principal

Lightbox effect with jQuery

Over the past few weeks, I have been in the process of finding the perfect way to create a lightbox effect of my own (both for professional and personal projects).  You can obviously rely on a existing library (such as Litebox), but if you want to have a full control over the lightbox, you might want to create it from scratch. This being said, we will not reinvent the wheel and we will get some help from jQuery to ease the manipulation.

First things first, for those who do not know...what is a lightbox? Here is what Wikipedia tells about it:

"Lightbox is a JavaScript technique used to display images and other web content using modal dialogs"
A lightbox effect is often used to enhance image galleries. Basically, suppose you display a series of thumbnails on your page. If the user wants to see the full-size picture, he has to click on the thumbnail, which will then open the image in a new tab or in a new window. This is quite unpractical, since it breaks the flow of navigation. Most users do not want to be redirected and wish to stay on the page. By adding a lightbox effect to your page, you can force each thumbnail to open a popup window with the full-size picture on the very page of the gallery.

Our goal here is to implement a lightbox effect on a series of thumbnails (so when clicking on these, a bigger picture is displayed), but also on a list of links. In this case, the lightbox effect will display the target window. Let's started!

1. Lightbox effect on images

Say your HTML code for the image gallery looks as such:

<div id=myGallery>
<div class="thmb">
<a href="http://.../mypic1.jpg"><img src="http://.../mypicThumb1.jpg"></a>
</div>
<div class="thmb">
<a href="http://.../mypic2.jpg"><img src="http://.../mypicThumb2.jpg"></a>
</div>
<div class="thmb">
<a href="http://.../mypic3.jpg"><img src="http://.../mypicThumb3.jpg"></a>
</div>
</div>

Currently, each thumbnail is anchored, so that when you click on it, it will open a new window/tab displaying the picture with its original size. 

Our first modification is to place the HREF url in a custom attribute, say tgt (for target):

<a href="#" tgt="http://.../mypic1.jpg"><img src="http://.../mypicThumb1.jpg"></a>

Doing so, we prevent the link from opening (that would prevent the script that is coming to work), yet keeping the full URL.

Since we are using jQuery, include the library in your header. Now onto the actual script :)

// when the page has finished loading
jQuery(document).ready(function(){

// adds a click listener on the class "thmb" (could be on the anchor or on the image)
$(".thmb").click(function(){

// if the lightbox does not exist yet (should not in any case, it's a safety check)
if($("#mylightbox").length==0){

// a few variables we will need
var sH=$(document).height(), sW=$(document).width(), scPos=$(document).scrollTop();
var tgtURL=$(this).contents().find("a").attr("tgt");

// creates a transparent grey background on the top of the page
$("body").css("overflow","hidden");
$("body").append("<div id=mylightbox style='position:absolute; z-index:1000; top:0px; left:0px; opacity:0.75; filter:opacity(alpha=0,75); width:"+(sW+20)+"px; height:"+sH+"px; background:#aaa;'></div>");

// we need now to add the full size picture above the grey background
$("body").append("<div id=full-image-bg style='z-index:1001; width:100%; height:100%; position:absolute; left:0px; top:"+scPos+"px;'><img id=full-image-img src='"+tgtURL+"' style='width:auto; height:auto; cursor:pointer; position:absolute;'/></div>");

/* now that the picture has loaded (autosize), we retrieve its dimensions in pixels, as well as the parent div's...this way we can center the picture with javascript (safer than CSS for crossbrowsing) */
var picW=$("#full-image-img").width(), picH=$("#full-image-img").height(), lbW=$("#full-image-bg").width(), lbH=$("#full-image-bg").height();
var cX=(lbW/2)-(picW/2), cY=(lbH/2)-(picH/2);

// center the picture (using some chaining for a change)
$("#
full-image-img").css("left",cX+"px").css("top",cY+"px");

// finally add an on-click listener on the picture to close the lightbox (a close button could be used instead)
$("#full-image-img").click(function(){
$("#
full-image-bg").remove();
$("#
mylightbox").remove();
if($("body").height() > $(window).height()){
$("body").css("overflow","scroll");
$("body").css("overflow-x","hidden");}
});

}
});
});



2. Lightbox effect on URLs

If the previous part was clear to you, there will be no problem understanding this bit. Basically, the lightbox script is almost the same. The only difference is that we do not create an IMG object in the lightbox window, but an IFRAME component, whose SRC equals tgt and whose border is defined as "none". Do not an autosize. Preferrably, define a fixed width/height (might involves some scrolling of the iframe though, but for short transaction pages, such a "share to Z site" for instance, it is perfectly fine).

[...] <iframe id='lightbox-url-frame src='"+tgtURL+"' style='width:800px; height:500px; border:none;' frameborder=none> [...]


Last but not least, a click event to remove the lightbox is irrelevant here, since the user most likely has to interact with the iframe. Instead, append an INPUT control on the lightbox, to which you will bind the click handler.

 

Commentaires

Posts les plus consultés de ce blog

HTML tables and auto-sizing cell heights : a workaround

Although this was common practice in the early days of the Web, working with HTML tables when it comes to building a webpage layout should be avoided as much as possible nowadays. CSS offers all the tools that are needed to create perfectly dynamic and flexible layouts, so you really should only rely on HTML tables to present actual data. This being said, it happens that you don't have the choice, and that this just what I've learned recently in my work. In the context of a client project, the framework I've had to use (Peoplesoft, an HRIS system) indeed generates HTML pages presenting a structure quite "2000"-ish, consisting in a complex nesting of HTML tables. Moreover, each time you add a component on the page (via the system itself, not when hardcoding it), a system TABLE is create to wrap the object. This can cause obviously a lot of problems, but in this case, my problem was quite specific. A few pages of the system use a well-defined table layout :

Lightbox effect with jQuery (3) - ready-to-use library

I've been pretty busy with work over the past days, but I managed to finalize my lightbox javascript library still. Although I can't confirm it is 100% cross-browser, it seems to be running well under IE8/9, Firefox and Chrome. I reckon it should work as well on Safari, but you never know. The actual library and a sample HTML file can be found here: https://sourceforge.net/projects/delightbox/files/ How to use ? First, include jQuery and, needless to say, the library. Second, call the function init from dlb , once the DOM has been fully created and the page is ready. <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> <script type="text/javascript" src="./delightbox-latest.js"></script>         <script>         jQuery(document).ready(function(){             dlb.init();         }); </script> Delightbox allows to create a lightbox e

A binary clock in Javascript

Just a short post to share a tiny project I recently worked on: a binary clock. The script is written in pure Javascript (no jQuery for a change), and the design of the buttons was rapidly made in Photoshop, so nothing fancy...but I really wanted to create this :-) http://manuthommes.be/toolbox/binaryclock/ As usual, the code is not obfuscated so you can have a look and feel free to copy/edit.