Creating a Lightbox Effect
In the next few exercises you’ll use several of the DOM manipulators to create a lightbox effect. Many websites use a lightbox effect to show enlargements of photographs centered and highlighted on web pages. You’ll be able to use the effect on your web pages too, once you’ve learned how to put together the function.
Some of the manipulators that you’ll use during the exercise are specifically designed for getting or modifying information about CSS. These are described in Table 4.2.
Table 4.2. DOM CSS Manipulators
Method |
Use It To... |
css() |
Get or set the value of a style property for the first element in the set of selected elements. |
height() |
Get the current computed height for the first element in the set of selected elements. |
innerHeight() |
Get the current computed height for the first element in the set of selected elements, including the padding but not the border. |
outerHeight() |
Get the current computed height for the first element in the set of selected elements, including padding, border, and optionally, margin. |
width() |
Get the current computed width for the first element in the set of selected elements. |
innerWidth() |
Get the current computed width for the first element in the set of selected elements, including the padding but not the border. |
outerWidth() |
Get the current computed width for the first element in the set of selected elements, including padding and border. |
offset() |
Get the current coordinates of the first element in the set of selected elements, relative to the document. |
position() |
Get the current coordinates of the first element in the set of selected elements, relative to its parent element. |
scrollLeft() |
Get the current number of pixels hidden from view to the left of any scrollable area for the first element in the set of selected elements. |
scrollTop() |
Get the number of pixels hidden above any scrollable area for the first element in the set of matched elements. |
remove() |
Remove the set of selected elements from the DOM. |
removeAttr() |
Remove an attribute from each of the selected elements. |
replaceAll() |
Replace each target element with the set of selected elements. |
replaceWith() |
Replace each element in the set of selected elements with new content. |
wrap() |
Wrap an HTML structure around each element in the set of selected elements. |
unwrap() |
Remove the parents of the set of selected elements from the DOM. |
wrapAll() |
Wrap an HTML structure around all elements in the set of selected elements. |
wrapInner() |
Wrap an HTML structure around the content of each element in the set of selected elements. |
The first order of business is covering the current page with a translucent background on which the photograph will be displayed.
To use the append() method to display a translucent shade
- Open gallery.html in your text editor and add the data-photo attribute to each of the list items (Script 4.1.html):
<li> <img src="images/thumb_lv01.jpg"
data-photo="images/lv01.jpg"
alt="Classic Sign - Las Vegas" /> </li> <li> <img src="images/thumb_lv02.jpg"data-photo="images/lv02.jpg"
alt="New York New York - Las Vegas" /> </li> <li> <img src="images/thumb_lv03.jpg"data-photo="images/lv03.jpg"
alt="Neon Lights - Las Vegas" /> </li> <li> <img src="images/thumb_lv04.jpg"data-photo="images/lv04.jpg"
alt="Stratosphere - Las Vegas" /> </li> <li> <img src="images/thumb_lv05.jpg"data-photo="images/lv05.jpg"
alt="Wynn Hotel - Las Vegas" /> </li> <li> <img src="images/thumb_lv06.jpg"data-photo="images/lv06.jpg"
alt="Paris - Las Vegas" /> </li> - Save the gallery.html file and upload it to your web server.
- Edit jquery.custom.js and insert the following code to add a translucent background to the browser window:
$('.imageGallery li img') .click(function() { $('body').append ('<div class="shade"></div>'); $('.shade') .css('opacity', 0.7).fadeIn(); });
- Save the jQuery file and upload it to your server.
- Click on any of the images in the photo gallery and the background should appear. There’s no way to get rid of it at this point without reloading the page. You’ll add code to remove it later .
For the backdrop to appear, you have to append a div to the body element of your page and declare the shade class on the div (the shade class is already defined for you in css/base.css). At this point, you apply a CSS opacity property (to make the backdrop translucent) and use fadeIn() to bring the backdrop into view. (More on fadeIn() and other effects in Chapter 8, “Creating Captivating Effects.”)
Take a look at your DOM inspection tool while you have the div applied to the body. Notice that the backdrop div is the last element within the body tags because append() inserts content at the end of the selected element .
With the backdrop in place, it’s time to add the photo. There will be two things you’ll have to take care of: preloading all the full-sized images and placing the image centered on the browser window.
The reason for preloading the images is to ensure that the lightbox function can properly measure the image and know how to place it within the window. The jQuery methods can’t get the height and width of an element that isn’t currently available in the DOM. Failing to perform this step results in the image not being centered properly .
You’ll also use the browser window’s height to set the size of the image to make sure the photo is fully displayed within the boundaries of the browser window. Many of the full-sized images in the example are either taller or wider than the browser window .
As a matter of organization, most developers will group functions like the image preloader near the top of their jQuery file. In this case, the preloader needs to have completed its job before the lightbox function is called, so let’s put the preloading function together first.
To create an image preloader using appendTo()
- Edit your jQuery file to add the image preloader:
function preload(arrayOfImages) { $(arrayOfImages).each(function(){ $('<img />') .attr('src',this) .appendTo('body') .css('display','none'); }); }
You start by declaring a function named preload. The function is given the argument of arrayOfImages. Once the function is called, the jQuery method each() loops through each item in the array that you’ll pass to the function. (More on each() in Chapter 9, “Turning on jQuery’s Utilities.”)
For each image, you append an image tag to the body. Then you set the src attribute for the image tag to the current image information. Finally, you make sure the images are not visible until you need them by setting their CSS display method to none.
Using appendTo() here makes perfect sense because it allows you to specify attributes more easily for each image tag prior to the tag being added to the page.
- Create the array inside a function call to preload:
preload([ 'images/lv01.jpg', 'images/lv02.jpg', 'images/lv03.jpg', 'images/lv04.jpg', 'images/lv05.jpg', 'images/lv06.jpg' ]);
The square brackets indicate a JavaScript array using JavaScript Object Notation. The path for each full-sized image has been specified in a comma-separated list. Have a look at your DOM inspector and you should see the image tags just before the closing body tag .
Now let’s add further to the lightbox function.
To use height() and width() to set an element’s size and position
- Open jquery.custom.js in your text editor.
- Add the following jQuery code to create an image tag:
var imgSRC = $(this).attr('data-photo'); var imgTAG = '<img src="'+ imgSRC + '" />';
This code should be added immediately after the line where you applied fadeIn() to the backdrop.
- Continue the function by adding the following code to append the modal window to the body and the image tag to the modal window:
$('body') .append('<div class="photoModal"> </div>'); $('.photoModal').html(imgTAG); $('.photoModal') .fadeIn('slow') .append('<div> <a href="#" class="closePhoto"> Close X</a></div>');
The additional append() method adds an anchor tag to the modal, which will be used for closing the photo.
- Enter the code to check the window’s height and apply the height to the image:
var windowHeight = $(window).height(); $('.photoModal img') .css('height', (windowHeight - 200));
You’ve subtracted 200 pixels from the window’s height to ensure that the image will fit in the browser window.
- Save information about the modal’s current height and width to two variables. These two variables will be applied to the modal to center it horizontally and vertically within the browser window:
var modalTopMargin = ($('.photoModal') .height() + 20) / 2; var modalLeftMargin = ($('.photoModal') .width() + 20) / 2;
The reason you add 20 to the height and width is because the CSS specified for the modal window has a border of 10 pixels per side .
- Add the code to apply the CSS to the modal:
$('.photoModal') .css({'margin-top' : -modalTopMargin, 'margin-left': -modalLeftMargin});
In the original CSS (see css/base.css) for the modal, the top-left corner is originally set to be in the center of the screen. The top-left corner of the browser window is at coordinates 0, 0 .
To make sure the photo is centered, you apply negative measurements from the photo’s top-left corner to move it into position .
- Save the jQuery file and upload it to your web server. Reload gallery.html into your web page and click on one of the pictures .
There’s only one problem at this point: you can’t close a picture once you’ve opened it. Because you’ve added elements to the DOM that were not previously there, you’ll have to use a special way to attach event handlers to account for the new elements.
To close the picture using remove()
- Reload jquery.custom.js into your text editor.
- Add the following function to the file:
$('body') .on('click', '.closePhoto', function(e){ e.preventDefault(); $('.photoModal, .shade') .fadeOut(function(){ $(this).remove(); }); });
The on() method accounts for elements either in the DOM now or added in the future. You use it to bind event handlers to items within a selected element. In the exercise, you attached the click event handler to the body and specified that the handler should answer to any item having the closePhoto class. You’ll recall that you appended an anchor tag having the class closePhoto in the previous exercise.
Once the tag is clicked, the photo modal and the backdrop are faded and then removed using the remove() method, allowing the lightbox function to be reset for its next performance.
You have undoubtedly noticed the preventDefault() method used here. You passed the click event e to the function:
function(e){...}
To keep the link from acting normally, which is typically navigating to another page, you applied the preventDefault() method to the event, which does what it says—it prevents the default event action from occurring.
- Save the file and upload it to your web server.
- Reload the gallery.html page. Click on an image and then click on the “Close X” link at the bottom right of the image. Your gallery page has returned to normal.