2 * jQuery lightBox plugin
3 * This jQuery plugin was inspired and based on Lightbox 2 by Lokesh Dhakar (http://www.huddletogether.com/projects/lightbox2/)
4 * and adapted to me for use like a plugin from jQuery.
5 * @name jquery-lightbox-0.5.js
6 * @author Leandro Vieira Pinho - http://leandrovieira.com
9 * @category jQuery plugin
10 * @copyright (c) 2008 Leandro Vieira Pinho (leandrovieira.com)
11 * @license CC Attribution-No Derivative Works 2.5 Brazil - http://creativecommons.org/licenses/by-nd/2.5/br/deed.en_US
12 * @example Visit http://leandrovieira.com/projects/jquery/lightbox/ for more informations about this jQuery plugin
15 // Offering a Custom Alias suport - More info: http://docs.jquery.com/Plugins/Authoring#Custom_Alias
18 * $ is an alias to jQuery object
21 $.fn
.lightBox = function(settings
) {
22 // Settings to configure the jQuery lightBox plugin how you like
23 settings
= jQuery
.extend({
24 // Configuration related to overlay
25 overlayBgColor: '#000', // (string) Background color to overlay; inform a hexadecimal value like: #RRGGBB. Where RR, GG, and BB are the hexadecimal values for the red, green, and blue values of the color.
26 overlayOpacity: 0.8, // (integer) Opacity value to overlay; inform: 0.X. Where X are number from 0 to 9
27 // Configuration related to navigation
28 fixedNavigation: false, // (boolean) Boolean that informs if the navigation (next and prev button) will be fixed or not in the interface.
29 // Configuration related to images
30 imageLoading: 'img/lightbox-ico-loading.gif', // (string) Path and the name of the loading icon
31 imageBtnPrev: 'img/lightbox-btn-prev.gif', // (string) Path and the name of the prev button image
32 imageBtnNext: 'img/lightbox-btn-next.gif', // (string) Path and the name of the next button image
33 imageBtnClose: 'img/lightbox-btn-close.gif', // (string) Path and the name of the close btn
34 imageBlank: 'img/lightbox-blank.gif', // (string) Path and the name of a blank image (one pixel)
35 // Configuration related to container image box
36 containerBorderSize: 10, // (integer) If you adjust the padding in the CSS for the container, #lightbox-container-image-box, you will need to update this value
37 containerResizeSpeed: 400, // (integer) Specify the resize duration of container image. These number are miliseconds. 400 is default.
38 // Configuration related to texts in caption. For example: Image 2 of 8. You can alter either "Image" and "of" texts.
39 txtImage: 'Image', // (string) Specify text "Image"
40 txtOf: 'of', // (string) Specify text "of"
41 // Configuration related to keyboard navigation
42 keyToClose: 'c', // (string) (c = close) Letter to close the jQuery lightBox interface. Beyond this letter, the letter X and the SCAPE key is used to.
43 keyToPrev: 'p', // (string) (p = previous) Letter to show the previous image
44 keyToNext: 'n', // (string) (n = next) Letter to show the next image.
45 // Don´t alter these variables in any way
49 // Caching the jQuery object with all elements matched
50 var jQueryMatchedObj
= this; // This, in this context, refer to jQuery object
52 * Initializing the plugin calling the start function
54 * @return boolean false
56 function _initialize() {
57 _start(this,jQueryMatchedObj
); // This, in this context, refer to object (link) which the user have clicked
58 return false; // Avoid the browser following the link
61 * Start the jQuery lightBox plugin
63 * @param object objClicked The object (link) whick the user have clicked
64 * @param object jQueryMatchedObj The jQuery object with all elements matched
66 function _start(objClicked
,jQueryMatchedObj
) {
67 // Hime some elements to avoid conflict with overlay in IE. These elements appear above the overlay.
68 $('embed, object, select').css({ 'visibility' : 'hidden' });
69 // Call the function to create the markup structure; style some elements; assign events in some elements.
71 // Unset total images in imageArray
72 settings
.imageArray
.length
= 0;
73 // Unset image active information
74 settings
.activeImage
= 0;
75 // We have an image set? Or just an image? Let´s see it.
76 if ( jQueryMatchedObj
.length
== 1 ) {
77 settings
.imageArray
.push(new Array(objClicked
.getAttribute('href'),objClicked
.getAttribute('title')));
79 // Add an Array (as many as we have), with href and title atributes, inside the Array that storage the images references
80 for ( var i
= 0; i
< jQueryMatchedObj
.length
; i
++ ) {
81 settings
.imageArray
.push(new Array(jQueryMatchedObj
[i
].getAttribute('href'),jQueryMatchedObj
[i
].getAttribute('title')));
84 while ( settings
.imageArray
[settings
.activeImage
][0] != objClicked
.getAttribute('href') ) {
85 settings
.activeImage
++;
87 // Call the function that prepares image exibition
91 * Create the jQuery lightBox plugin interface
93 * The HTML markup will be like that:
94 <div id="jquery-overlay"></div>
95 <div id="jquery-lightbox">
96 <div id="lightbox-container-image-box">
97 <div id="lightbox-container-image">
98 <img src="../fotos/XX.jpg" id="lightbox-image">
99 <div id="lightbox-nav">
100 <a href="#" id="lightbox-nav-btnPrev"></a>
101 <a href="#" id="lightbox-nav-btnNext"></a>
103 <div id="lightbox-loading">
104 <a href="#" id="lightbox-loading-link">
105 <img src="../img/lightbox-ico-loading.gif">
110 <div id="lightbox-container-image-data-box">
111 <div id="lightbox-container-image-data">
112 <div id="lightbox-image-details">
113 <span id="lightbox-image-details-caption"></span>
114 <span id="lightbox-image-details-currentNumber"></span>
116 <div id="lightbox-secNav">
117 <a href="#" id="lightbox-secNav-btnClose">
118 <img src="../img/lightbox-btn-close.gif">
126 function _set_interface() {
127 // Apply the HTML markup into body tag
128 $('body').append('<div id="jquery-overlay"></div><div id="jquery-lightbox"><div id="lightbox-container-image-box"><div id="lightbox-container-image"><img id="lightbox-image"><div style="" id="lightbox-nav"><a href="#" id="lightbox-nav-btnPrev"></a><a href="#" id="lightbox-nav-btnNext"></a></div><div id="lightbox-loading"><a href="#" id="lightbox-loading-link"><img src="' + settings
.imageLoading
+ '"></a></div></div></div><div id="lightbox-container-image-data-box"><div id="lightbox-container-image-data"><div id="lightbox-image-details"><span id="lightbox-image-details-caption"></span><span id="lightbox-image-details-currentNumber"></span></div><div id="lightbox-secNav"><a href="#" id="lightbox-secNav-btnClose"><img src="' + settings
.imageBtnClose
+ '"></a></div></div></div></div>');
130 var arrPageSizes
= ___getPageSize();
131 // Style overlay and show it
132 $('#jquery-overlay').css({
133 backgroundColor: settings
.overlayBgColor
,
134 opacity: settings
.overlayOpacity
,
135 width: arrPageSizes
[0],
136 height: arrPageSizes
[1]
139 var arrPageScroll
= ___getPageScroll();
140 // Calculate top and left offset for the jquery-lightbox div object and show it
141 $('#jquery-lightbox').css({
142 top: arrPageScroll
[1] + (arrPageSizes
[3] / 10),
143 left: arrPageScroll
[0]
145 // Assigning click events in elements to close overlay
146 $('#jquery-overlay,#jquery-lightbox').click(function() {
149 // Assign the _finish function to lightbox-loading-link and lightbox-secNav-btnClose objects
150 $('#lightbox-loading-link,#lightbox-secNav-btnClose').click(function() {
154 // If window was resized, calculate the new overlay dimensions
155 $(window
).resize(function() {
157 var arrPageSizes
= ___getPageSize();
158 // Style overlay and show it
159 $('#jquery-overlay').css({
160 width: arrPageSizes
[0],
161 height: arrPageSizes
[1]
164 var arrPageScroll
= ___getPageScroll();
165 // Calculate top and left offset for the jquery-lightbox div object and show it
166 $('#jquery-lightbox').css({
167 top: arrPageScroll
[1] + (arrPageSizes
[3] / 10),
168 left: arrPageScroll
[0]
173 * Prepares image exibition; doing a image´s preloader to calculate it´s size
176 function _set_image_to_view() { // show the loading
178 $('#lightbox-loading').show();
179 if ( settings
.fixedNavigation
) {
180 $('#lightbox-image,#lightbox-container-image-data-box,#lightbox-image-details-currentNumber').hide();
182 // Hide some elements
183 $('#lightbox-image,#lightbox-nav,#lightbox-nav-btnPrev,#lightbox-nav-btnNext,#lightbox-container-image-data-box,#lightbox-image-details-currentNumber').hide();
185 // Image preload process
186 var objImagePreloader
= new Image();
187 objImagePreloader
.onload = function() {
188 $('#lightbox-image').attr('src',settings
.imageArray
[settings
.activeImage
][0]);
189 // Perfomance an effect in the image container resizing it
190 _resize_container_image_box(objImagePreloader
.width
,objImagePreloader
.height
);
191 // clear onLoad, IE behaves irratically with animated gifs otherwise
192 objImagePreloader
.onload=function(){};
194 objImagePreloader
.src
= settings
.imageArray
[settings
.activeImage
][0];
197 * Perfomance an effect in the image container resizing it
199 * @param integer intImageWidth The image´s width that will be showed
200 * @param integer intImageHeight The image´s height that will be showed
202 function _resize_container_image_box(intImageWidth
,intImageHeight
) {
203 // Get current width and height
204 var intCurrentWidth
= $('#lightbox-container-image-box').width();
205 var intCurrentHeight
= $('#lightbox-container-image-box').height();
206 // Get the width and height of the selected image plus the padding
207 var intWidth
= (intImageWidth
+ (settings
.containerBorderSize
* 2)); // Plus the image´s width and the left and right padding value
208 var intHeight
= (intImageHeight
+ (settings
.containerBorderSize
* 2)); // Plus the image´s height and the left and right padding value
210 var intDiffW
= intCurrentWidth
- intWidth
;
211 var intDiffH
= intCurrentHeight
- intHeight
;
212 // Perfomance the effect
213 $('#lightbox-container-image-box').animate({ width: intWidth
, height: intHeight
},settings
.containerResizeSpeed
,function() { _show_image(); });
214 if ( ( intDiffW
== 0 ) && ( intDiffH
== 0 ) ) {
215 if ( $.browser
.msie
) {
221 $('#lightbox-container-image-data-box').css({ width: intImageWidth
});
222 $('#lightbox-nav-btnPrev,#lightbox-nav-btnNext').css({ height: intImageHeight
+ (settings
.containerBorderSize
* 2) });
225 * Show the prepared image
228 function _show_image() {
229 $('#lightbox-loading').hide();
230 $('#lightbox-image').fadeIn(function() {
234 _preload_neighbor_images();
237 * Show the image information
240 function _show_image_data() {
241 $('#lightbox-container-image-data-box').slideDown('fast');
242 $('#lightbox-image-details-caption').hide();
243 if ( settings
.imageArray
[settings
.activeImage
][1] ) {
244 $('#lightbox-image-details-caption').html(settings
.imageArray
[settings
.activeImage
][1]).show();
246 // If we have a image set, display 'Image X of X'
247 if ( settings
.imageArray
.length
> 1 ) {
248 $('#lightbox-image-details-currentNumber').html(settings
.txtImage
+ ' ' + ( settings
.activeImage
+ 1 ) + ' ' + settings
.txtOf
+ ' ' + settings
.imageArray
.length
).show();
252 * Display the button navigations
255 function _set_navigation() {
256 $('#lightbox-nav').show();
258 // Instead to define this configuration in CSS file, we define here. And it´s need to IE. Just.
259 $('#lightbox-nav-btnPrev,#lightbox-nav-btnNext').css({ 'background' : 'transparent url(' + settings
.imageBlank
+ ') no-repeat' });
261 // Show the prev button, if not the first image in set
262 if ( settings
.activeImage
!= 0 ) {
263 if ( settings
.fixedNavigation
) {
264 $('#lightbox-nav-btnPrev').css({ 'background' : 'url(' + settings
.imageBtnPrev
+ ') left 15% no-repeat' })
266 .bind('click',function() {
267 settings
.activeImage
= settings
.activeImage
- 1;
268 _set_image_to_view();
272 // Show the images button for Next buttons
273 $('#lightbox-nav-btnPrev').unbind().hover(function() {
274 $(this).css({ 'background' : 'url(' + settings
.imageBtnPrev
+ ') left 15% no-repeat' });
276 $(this).css({ 'background' : 'transparent url(' + settings
.imageBlank
+ ') no-repeat' });
277 }).show().bind('click',function() {
278 settings
.activeImage
= settings
.activeImage
- 1;
279 _set_image_to_view();
285 // Show the next button, if not the last image in set
286 if ( settings
.activeImage
!= ( settings
.imageArray
.length
-1 ) ) {
287 if ( settings
.fixedNavigation
) {
288 $('#lightbox-nav-btnNext').css({ 'background' : 'url(' + settings
.imageBtnNext
+ ') right 15% no-repeat' })
290 .bind('click',function() {
291 settings
.activeImage
= settings
.activeImage
+ 1;
292 _set_image_to_view();
296 // Show the images button for Next buttons
297 $('#lightbox-nav-btnNext').unbind().hover(function() {
298 $(this).css({ 'background' : 'url(' + settings
.imageBtnNext
+ ') right 15% no-repeat' });
300 $(this).css({ 'background' : 'transparent url(' + settings
.imageBlank
+ ') no-repeat' });
301 }).show().bind('click',function() {
302 settings
.activeImage
= settings
.activeImage
+ 1;
303 _set_image_to_view();
308 // Enable keyboard navigation
309 _enable_keyboard_navigation();
312 * Enable a support to keyboard navigation
315 function _enable_keyboard_navigation() {
316 $(document
).keydown(function(objEvent
) {
317 _keyboard_action(objEvent
);
321 * Disable the support to keyboard navigation
324 function _disable_keyboard_navigation() {
325 $(document
).unbind();
328 * Perform the keyboard actions
331 function _keyboard_action(objEvent
) {
333 if ( objEvent
== null ) {
334 keycode
= event
.keyCode
;
338 keycode
= objEvent
.keyCode
;
339 escapeKey
= objEvent
.DOM_VK_ESCAPE
;
341 // Get the key in lower case form
342 key
= String
.fromCharCode(keycode
).toLowerCase();
343 // Verify the keys to close the ligthBox
344 if ( ( key
== settings
.keyToClose
) || ( key
== 'x' ) || ( keycode
== escapeKey
) ) {
347 // Verify the key to show the previous image
348 if ( ( key
== settings
.keyToPrev
) || ( keycode
== 37 ) ) {
349 // If we´re not showing the first image, call the previous
350 if ( settings
.activeImage
!= 0 ) {
351 settings
.activeImage
= settings
.activeImage
- 1;
352 _set_image_to_view();
353 _disable_keyboard_navigation();
356 // Verify the key to show the next image
357 if ( ( key
== settings
.keyToNext
) || ( keycode
== 39 ) ) {
358 // If we´re not showing the last image, call the next
359 if ( settings
.activeImage
!= ( settings
.imageArray
.length
- 1 ) ) {
360 settings
.activeImage
= settings
.activeImage
+ 1;
361 _set_image_to_view();
362 _disable_keyboard_navigation();
367 * Preload prev and next images being showed
370 function _preload_neighbor_images() {
371 if ( (settings
.imageArray
.length
-1) > settings
.activeImage
) {
372 objNext
= new Image();
373 objNext
.src
= settings
.imageArray
[settings
.activeImage
+ 1][0];
375 if ( settings
.activeImage
> 0 ) {
376 objPrev
= new Image();
377 objPrev
.src
= settings
.imageArray
[settings
.activeImage
-1][0];
381 * Remove jQuery lightBox plugin HTML markup
385 $('#jquery-lightbox').remove();
386 $('#jquery-overlay').fadeOut(function() { $('#jquery-overlay').remove(); });
387 // Show some elements to avoid conflict with overlay in IE. These elements appear above the overlay.
388 $('embed, object, select').css({ 'visibility' : 'visible' });
392 * getPageSize() by quirksmode.com
394 * @return Array Return an array with page width, height and window width, height
396 function ___getPageSize() {
397 var xScroll
, yScroll
;
398 if (window
.innerHeight
&& window
.scrollMaxY
) {
399 xScroll
= window
.innerWidth
+ window
.scrollMaxX
;
400 yScroll
= window
.innerHeight
+ window
.scrollMaxY
;
401 } else if (document
.body
.scrollHeight
> document
.body
.offsetHeight
){ // all but Explorer Mac
402 xScroll
= document
.body
.scrollWidth
;
403 yScroll
= document
.body
.scrollHeight
;
404 } else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
405 xScroll
= document
.body
.offsetWidth
;
406 yScroll
= document
.body
.offsetHeight
;
408 var windowWidth
, windowHeight
;
409 if (self
.innerHeight
) { // all except Explorer
410 if(document
.documentElement
.clientWidth
){
411 windowWidth
= document
.documentElement
.clientWidth
;
413 windowWidth
= self
.innerWidth
;
415 windowHeight
= self
.innerHeight
;
416 } else if (document
.documentElement
&& document
.documentElement
.clientHeight
) { // Explorer 6 Strict Mode
417 windowWidth
= document
.documentElement
.clientWidth
;
418 windowHeight
= document
.documentElement
.clientHeight
;
419 } else if (document
.body
) { // other Explorers
420 windowWidth
= document
.body
.clientWidth
;
421 windowHeight
= document
.body
.clientHeight
;
423 // for small pages with total height less then height of the viewport
424 if(yScroll
< windowHeight
){
425 pageHeight
= windowHeight
;
427 pageHeight
= yScroll
;
429 // for small pages with total width less then width of the viewport
430 if(xScroll
< windowWidth
){
433 pageWidth
= windowWidth
;
435 arrayPageSize
= new Array(pageWidth
,pageHeight
,windowWidth
,windowHeight
);
436 return arrayPageSize
;
440 * getPageScroll() by quirksmode.com
442 * @return Array Return an array with x,y page scroll values.
444 function ___getPageScroll() {
445 var xScroll
, yScroll
;
446 if (self
.pageYOffset
) {
447 yScroll
= self
.pageYOffset
;
448 xScroll
= self
.pageXOffset
;
449 } else if (document
.documentElement
&& document
.documentElement
.scrollTop
) { // Explorer 6 Strict
450 yScroll
= document
.documentElement
.scrollTop
;
451 xScroll
= document
.documentElement
.scrollLeft
;
452 } else if (document
.body
) {// all other Explorers
453 yScroll
= document
.body
.scrollTop
;
454 xScroll
= document
.body
.scrollLeft
;
456 arrayPageScroll
= new Array(xScroll
,yScroll
);
457 return arrayPageScroll
;
460 * Stop the code execution from a escified time in milisecond
463 function ___pause(ms
) {
464 var date
= new Date();
466 do { var curDate
= new Date(); }
467 while ( curDate
- date
< ms
);
469 // Return the jQuery object for chaining. The unbind method is used to avoid click conflict when the plugin is called more than once
470 return this.unbind('click').click(_initialize
);
472 })(jQuery
); // Call and execute the function immediately passing the jQuery object