lightbox.csslightbox.js のデフォルトのソースコード(Lightbox v2.9.0 2016-11-06)
lightbox.css(全部)

1	/* Preload images */
2	body:after {
3	  content: url(../images/close.png) url(../images/loading.gif) url(../images/prev.png) url(../images/next.png);
4	  display: none;
5	}
6	
7	body.lb-disable-scrolling {
8	  overflow: hidden;
9	}
10	
11	.lightboxOverlay {
12	  position: absolute;
13	  top: 0;
14	  left: 0;
15	  z-index: 9999;
16	  background-color: black;
17	  filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=80);
18	  opacity: 0.8;
19	  display: none;
20	}
21	
22	.lightbox {
23	  position: absolute;
24	  left: 0;
25	  width: 100%;
26	  z-index: 10000;
27	  text-align: center;
28	  line-height: 0;
29	  font-weight: normal;
30	}
31	
32	.lightbox .lb-image {
33	  display: block;
34	  height: auto;
35	  max-width: inherit;
36	  max-height: none;
37	  border-radius: 3px;
38	
39	  /* Image border */
40	  border: 4px solid white;
41	}
42	
43	.lightbox a img {
44	  border: none;
45	}
46	
47	.lb-outerContainer {
48	  position: relative;
49	  *zoom: 1;
50	  width: 250px;
51	  height: 250px;
52	  margin: 0 auto;
53	  border-radius: 4px;
54	
55	  /* Background color behind image.
56	     This is visible during transitions. */
57	  background-color: white;
58	}
59	
60	.lb-outerContainer:after {
61	  content: "";
62	  display: table;
63	  clear: both;
64	}
65	
66	.lb-loader {
67	  position: absolute;
68	  top: 43%;
69	  left: 0;
70	  height: 25%;
71	  width: 100%;
72	  text-align: center;
73	  line-height: 0;
74	}
75	
76	.lb-cancel {
77	  display: block;
78	  width: 32px;
79	  height: 32px;
80	  margin: 0 auto;
81	  background: url(../images/loading.gif) no-repeat;
82	}
83	
84	.lb-nav {
85	  position: absolute;
86	  top: 0;
87	  left: 0;
88	  height: 100%;
89	  width: 100%;
90	  z-index: 10;
91	}
92	
93	.lb-container > .nav {
94	  left: 0;
95	}
96	
97	.lb-nav a {
98	  outline: none;
99	  background-image: url('data:image/gif;base64,R0lGODlhAQABAPAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==');
100	}
101	
102	.lb-prev, .lb-next {
103	  height: 100%;
104	  cursor: pointer;
105	  display: block;
106	}
107	
108	.lb-nav a.lb-prev {
109	  width: 34%;
110	  left: 0;
111	  float: left;
112	  background: url(../images/prev.png) left 48% no-repeat;
113	  filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
114	  opacity: 0;
115	  -webkit-transition: opacity 0.6s;
116	  -moz-transition: opacity 0.6s;
117	  -o-transition: opacity 0.6s;
118	  transition: opacity 0.6s;
119	}
120	
121	.lb-nav a.lb-prev:hover {
122	  filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
123	  opacity: 1;
124	}
125	
126	.lb-nav a.lb-next {
127	  width: 64%;
128	  right: 0;
129	  float: right;
130	  background: url(../images/next.png) right 48% no-repeat;
131	  filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
132	  opacity: 0;
133	  -webkit-transition: opacity 0.6s;
134	  -moz-transition: opacity 0.6s;
135	  -o-transition: opacity 0.6s;
136	  transition: opacity 0.6s;
137	}
138	
139	.lb-nav a.lb-next:hover {
140	  filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
141	  opacity: 1;
142	}
143	
144	.lb-dataContainer {
145	  margin: 0 auto;
146	  padding-top: 5px;
147	  *zoom: 1;
148	  width: 100%;
149	  -moz-border-radius-bottomleft: 4px;
150	  -webkit-border-bottom-left-radius: 4px;
151	  border-bottom-left-radius: 4px;
152	  -moz-border-radius-bottomright: 4px;
153	  -webkit-border-bottom-right-radius: 4px;
154	  border-bottom-right-radius: 4px;
155	}
156	
157	.lb-dataContainer:after {
158	  content: "";
159	  display: table;
160	  clear: both;
161	}
162	
163	.lb-data {
164	  padding: 0 4px;
165	  color: #ccc;
166	}
167	
168	.lb-data .lb-details {
169	  width: 80%; /* 85  */
170	  float: left;
171	  text-align: left;
172	  line-height: 1.1em;
173	}
174	
175	.lb-data .lb-caption {
176	  font-size: 13px;
177	  font-weight: bold;
178	  line-height: 1em;
179	}
180	
181	.lb-data .lb-caption a {
182	  color: #4ae;
183	}
184	
185	.lb-data .lb-number {
186	  display: block;
187	  clear: left;
188	  padding-bottom: 1em;
189	  font-size: 12px;
190	  color: #999999;
191	}
192	
193	.lb-data .lb-close {
194	  display: block;
195	  float: right;
196	  width: 30px;
197	  height: 30px;
198	  background: url(../images/close.png) top right no-repeat;
199	  text-align: right;
200	  outline: none;
201	  filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=70);
202	  opacity: 0.7;
203	  -webkit-transition: opacity 0.2s;
204	  -moz-transition: opacity 0.2s;
205	  -o-transition: opacity 0.2s;
206	  transition: opacity 0.2s;
207	}
208	
209	.lb-data .lb-close:hover {
210	  cursor: pointer;
211	  filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
212	  opacity: 1;
213	}
lightbox.js(全部)

1	/*!
2	 * Lightbox v2.9.0
3	 * by Lokesh Dhakar
4	 *
5	 * More info:
6	 * http://lokeshdhakar.com/projects/lightbox2/
7	 *
8	 * Copyright 2007, 2015 Lokesh Dhakar
9	 * Released under the MIT license
10	 * https://github.com/lokesh/lightbox2/blob/master/LICENSE
11	 */
12	
13	// Uses Node, AMD or browser globals to create a module.
14	(function (root, factory) {
15	    if (typeof define === 'function' && define.amd) {
16	        // AMD. Register as an anonymous module.
17	        define(['jquery'], factory);
18	    } else if (typeof exports === 'object') {
19	        // Node. Does not work with strict CommonJS, but
20	        // only CommonJS-like environments that support module.exports,
21	        // like Node.
22	        module.exports = factory(require('jquery'));
23	    } else {
24	        // Browser globals (root is window)
25	        root.lightbox = factory(root.jQuery);
26	    }
27	}(this, function ($) {
28	
29	  function Lightbox(options) {
30	    this.album = [];
31	    this.currentImageIndex = void 0;
32	    this.init();
33	
34	    // options
35	    this.options = $.extend({}, this.constructor.defaults);
36	    this.option(options);
37	  }
38	
39	  // Descriptions of all options available on the demo site:
40	  // http://lokeshdhakar.com/projects/lightbox2/index.html#options
41	  Lightbox.defaults = {
42	    albumLabel: 'Image %1 of %2',
43	    alwaysShowNavOnTouchDevices: false,
44	    fadeDuration: 600,
45	    fitImagesInViewport: true,
46	    imageFadeDuration: 600,
47	    // maxWidth: 800,
48	    // maxHeight: 600,
49	    positionFromTop: 50,
50	    resizeDuration: 700,
51	    showImageNumberLabel: true,
52	    wrapAround: false,
53	    disableScrolling: false,
54	    /*
55	    Sanitize Title
56	    If the caption data is trusted, for example you are hardcoding it in, then leave this to false.
57	    This will free you to add html tags, such as links, in the caption.
58	
59	    If the caption data is user submitted or from some other untrusted source, then set this to true
60	    to prevent xss and other injection attacks.
61	     */
62	    sanitizeTitle: false
63	  };
64	
65	  Lightbox.prototype.option = function(options) {
66	    $.extend(this.options, options);
67	  };
68	
69	  Lightbox.prototype.imageCountLabel = function(currentImageNum, totalImages) {
70	    return this.options.albumLabel.replace(/%1/g, currentImageNum).replace(/%2/g, totalImages);
71	  };
72	
73	  Lightbox.prototype.init = function() {
74	    var self = this;
75	    // Both enable and build methods require the body tag to be in the DOM.
76	    $(document).ready(function() {
77	      self.enable();
78	      self.build();
79	    });
80	  };
81	
82	  // Loop through anchors and areamaps looking for either data-lightbox attributes or rel attributes
83	  // that contain 'lightbox'. When these are clicked, start lightbox.
84	  Lightbox.prototype.enable = function() {
85	    var self = this;
86	    $('body').on('click', 'a[rel^=lightbox], area[rel^=lightbox], a[data-lightbox], area[data-lightbox]', function(event) {
87	      self.start($(event.currentTarget));
88	      return false;
89	    });
90	  };
91	
92	  // Build html for the lightbox and the overlay.
93	  // Attach event handlers to the new DOM elements. click click click
94	  Lightbox.prototype.build = function() {
95	    var self = this;
96	    $('
').appendTo($('body')); 97 98 // Cache jQuery objects 99 this.$lightbox = $('#lightbox'); 100 this.$overlay = $('#lightboxOverlay'); 101 this.$outerContainer = this.$lightbox.find('.lb-outerContainer'); 102 this.$container = this.$lightbox.find('.lb-container'); 103 this.$image = this.$lightbox.find('.lb-image'); 104 this.$nav = this.$lightbox.find('.lb-nav'); 105 106 // Store css values for future lookup 107 this.containerPadding = { 108 top: parseInt(this.$container.css('padding-top'), 10), 109 right: parseInt(this.$container.css('padding-right'), 10), 110 bottom: parseInt(this.$container.css('padding-bottom'), 10), 111 left: parseInt(this.$container.css('padding-left'), 10) 112 }; 113 114 this.imageBorderWidth = { 115 top: parseInt(this.$image.css('border-top-width'), 10), 116 right: parseInt(this.$image.css('border-right-width'), 10), 117 bottom: parseInt(this.$image.css('border-bottom-width'), 10), 118 left: parseInt(this.$image.css('border-left-width'), 10) 119 }; 120 121 // Attach event handlers to the newly minted DOM elements 122 this.$overlay.hide().on('click', function() { 123 self.end(); 124 return false; 125 }); 126 127 this.$lightbox.hide().on('click', function(event) { 128 if ($(event.target).attr('id') === 'lightbox') { 129 self.end(); 130 } 131 return false; 132 }); 133 134 this.$outerContainer.on('click', function(event) { 135 if ($(event.target).attr('id') === 'lightbox') { 136 self.end(); 137 } 138 return false; 139 }); 140 141 this.$lightbox.find('.lb-prev').on('click', function() { 142 if (self.currentImageIndex === 0) { 143 self.changeImage(self.album.length - 1); 144 } else { 145 self.changeImage(self.currentImageIndex - 1); 146 } 147 return false; 148 }); 149 150 this.$lightbox.find('.lb-next').on('click', function() { 151 if (self.currentImageIndex === self.album.length - 1) { 152 self.changeImage(0); 153 } else { 154 self.changeImage(self.currentImageIndex + 1); 155 } 156 return false; 157 }); 158 159 /* 160 Show context menu for image on right-click 161 162 There is a div containing the navigation that spans the entire image and lives above of it. If 163 you right-click, you are right clicking this div and not the image. This prevents users from 164 saving the image or using other context menu actions with the image. 165 166 To fix this, when we detect the right mouse button is pressed down, but not yet clicked, we 167 set pointer-events to none on the nav div. This is so that the upcoming right-click event on 168 the next mouseup will bubble down to the image. Once the right-click/contextmenu event occurs 169 we set the pointer events back to auto for the nav div so it can capture hover and left-click 170 events as usual. 171 */ 172 this.$nav.on('mousedown', function(event) { 173 if (event.which === 3) { 174 self.$nav.css('pointer-events', 'none'); 175 176 self.$lightbox.one('contextmenu', function() { 177 setTimeout(function() { 178 this.$nav.css('pointer-events', 'auto'); 179 }.bind(self), 0); 180 }); 181 } 182 }); 183 184 185 this.$lightbox.find('.lb-loader, .lb-close').on('click', function() { 186 self.end(); 187 return false; 188 }); 189 }; 190 191 // Show overlay and lightbox. If the image is part of a set, add siblings to album array. 192 Lightbox.prototype.start = function($link) { 193 var self = this; 194 var $window = $(window); 195 196 $window.on('resize', $.proxy(this.sizeOverlay, this)); 197 198 $('select, object, embed').css({ 199 visibility: 'hidden' 200 }); 201 202 this.sizeOverlay(); 203 204 this.album = []; 205 var imageNumber = 0; 206 207 function addToAlbum($link) { 208 self.album.push({ 209 link: $link.attr('href'), 210 title: $link.attr('data-title') || $link.attr('title') 211 }); 212 } 213 214 // Support both data-lightbox attribute and rel attribute implementations 215 var dataLightboxValue = $link.attr('data-lightbox'); 216 var $links; 217 218 if (dataLightboxValue) { 219 $links = $($link.prop('tagName') + '[data-lightbox="' + dataLightboxValue + '"]'); 220 for (var i = 0; i < $links.length; i = ++i) { 221 addToAlbum($($links[i])); 222 if ($links[i] === $link[0]) { 223 imageNumber = i; 224 } 225 } 226 } else { 227 if ($link.attr('rel') === 'lightbox') { 228 // If image is not part of a set 229 addToAlbum($link); 230 } else { 231 // If image is part of a set 232 $links = $($link.prop('tagName') + '[rel="' + $link.attr('rel') + '"]'); 233 for (var j = 0; j < $links.length; j = ++j) { 234 addToAlbum($($links[j])); 235 if ($links[j] === $link[0]) { 236 imageNumber = j; 237 } 238 } 239 } 240 } 241 242 // Position Lightbox 243 var top = $window.scrollTop() + this.options.positionFromTop; 244 var left = $window.scrollLeft(); 245 this.$lightbox.css({ 246 top: top + 'px', 247 left: left + 'px' 248 }).fadeIn(this.options.fadeDuration); 249 250 // Disable scrolling of the page while open 251 if (this.options.disableScrolling) { 252 $('body').addClass('lb-disable-scrolling'); 253 } 254 255 this.changeImage(imageNumber); 256 }; 257 258 // Hide most UI elements in preparation for the animated resizing of the lightbox. 259 Lightbox.prototype.changeImage = function(imageNumber) { 260 var self = this; 261 262 this.disableKeyboardNav(); 263 var $image = this.$lightbox.find('.lb-image'); 264 265 this.$overlay.fadeIn(this.options.fadeDuration); 266 267 $('.lb-loader').fadeIn('slow'); 268 this.$lightbox.find('.lb-image, .lb-nav, .lb-prev, .lb-next, .lb-dataContainer, .lb-numbers, .lb-caption').hide(); 269 270 this.$outerContainer.addClass('animating'); 271 272 // When image to show is preloaded, we send the width and height to sizeContainer() 273 var preloader = new Image(); 274 preloader.onload = function() { 275 var $preloader; 276 var imageHeight; 277 var imageWidth; 278 var maxImageHeight; 279 var maxImageWidth; 280 var windowHeight; 281 var windowWidth; 282 283 $image.attr('src', self.album[imageNumber].link); 284 285 $preloader = $(preloader); 286 287 $image.width(preloader.width); 288 $image.height(preloader.height); 289 290 if (self.options.fitImagesInViewport) { 291 // Fit image inside the viewport. 292 // Take into account the border around the image and an additional 10px gutter on each side. 293 294 windowWidth = $(window).width(); 295 windowHeight = $(window).height(); 296 maxImageWidth = windowWidth - self.containerPadding.left - self.containerPadding.right - self.imageBorderWidth.left - self.imageBorderWidth.right - 20; 297 maxImageHeight = windowHeight - self.containerPadding.top - self.containerPadding.bottom - self.imageBorderWidth.top - self.imageBorderWidth.bottom - 120; 298 299 // Check if image size is larger then maxWidth|maxHeight in settings 300 if (self.options.maxWidth && self.options.maxWidth < maxImageWidth) { 301 maxImageWidth = self.options.maxWidth; 302 } 303 if (self.options.maxHeight && self.options.maxHeight < maxImageWidth) { 304 maxImageHeight = self.options.maxHeight; 305 } 306 307 // Is there a fitting issue? 308 if ((preloader.width > maxImageWidth) || (preloader.height > maxImageHeight)) { 309 if ((preloader.width / maxImageWidth) > (preloader.height / maxImageHeight)) { 310 imageWidth = maxImageWidth; 311 imageHeight = parseInt(preloader.height / (preloader.width / imageWidth), 10); 312 $image.width(imageWidth); 313 $image.height(imageHeight); 314 } else { 315 imageHeight = maxImageHeight; 316 imageWidth = parseInt(preloader.width / (preloader.height / imageHeight), 10); 317 $image.width(imageWidth); 318 $image.height(imageHeight); 319 } 320 } 321 } 322 self.sizeContainer($image.width(), $image.height()); 323 }; 324 325 preloader.src = this.album[imageNumber].link; 326 this.currentImageIndex = imageNumber; 327 }; 328 329 // Stretch overlay to fit the viewport 330 Lightbox.prototype.sizeOverlay = function() { 331 this.$overlay 332 .width($(document).width()) 333 .height($(document).height()); 334 }; 335 336 // Animate the size of the lightbox to fit the image we are showing 337 Lightbox.prototype.sizeContainer = function(imageWidth, imageHeight) { 338 var self = this; 339 340 var oldWidth = this.$outerContainer.outerWidth(); 341 var oldHeight = this.$outerContainer.outerHeight(); 342 var newWidth = imageWidth + this.containerPadding.left + this.containerPadding.right + this.imageBorderWidth.left + this.imageBorderWidth.right; 343 var newHeight = imageHeight + this.containerPadding.top + this.containerPadding.bottom + this.imageBorderWidth.top + this.imageBorderWidth.bottom; 344 345 function postResize() { 346 self.$lightbox.find('.lb-dataContainer').width(newWidth); 347 self.$lightbox.find('.lb-prevLink').height(newHeight); 348 self.$lightbox.find('.lb-nextLink').height(newHeight); 349 self.showImage(); 350 } 351 352 if (oldWidth !== newWidth || oldHeight !== newHeight) { 353 this.$outerContainer.animate({ 354 width: newWidth, 355 height: newHeight 356 }, this.options.resizeDuration, 'swing', function() { 357 postResize(); 358 }); 359 } else { 360 postResize(); 361 } 362 }; 363 364 // Display the image and its details and begin preload neighboring images. 365 Lightbox.prototype.showImage = function() { 366 this.$lightbox.find('.lb-loader').stop(true).hide(); 367 this.$lightbox.find('.lb-image').fadeIn(this.options.imageFadeDuration); 368 369 this.updateNav(); 370 this.updateDetails(); 371 this.preloadNeighboringImages(); 372 this.enableKeyboardNav(); 373 }; 374 375 // Display previous and next navigation if appropriate. 376 Lightbox.prototype.updateNav = function() { 377 // Check to see if the browser supports touch events. If so, we take the conservative approach 378 // and assume that mouse hover events are not supported and always show prev/next navigation 379 // arrows in image sets. 380 var alwaysShowNav = false; 381 try { 382 document.createEvent('TouchEvent'); 383 alwaysShowNav = (this.options.alwaysShowNavOnTouchDevices) ? true : false; 384 } catch (e) {} 385 386 this.$lightbox.find('.lb-nav').show(); 387 388 if (this.album.length > 1) { 389 if (this.options.wrapAround) { 390 if (alwaysShowNav) { 391 this.$lightbox.find('.lb-prev, .lb-next').css('opacity', '1'); 392 } 393 this.$lightbox.find('.lb-prev, .lb-next').show(); 394 } else { 395 if (this.currentImageIndex > 0) { 396 this.$lightbox.find('.lb-prev').show(); 397 if (alwaysShowNav) { 398 this.$lightbox.find('.lb-prev').css('opacity', '1'); 399 } 400 } 401 if (this.currentImageIndex < this.album.length - 1) { 402 this.$lightbox.find('.lb-next').show(); 403 if (alwaysShowNav) { 404 this.$lightbox.find('.lb-next').css('opacity', '1'); 405 } 406 } 407 } 408 } 409 }; 410 411 // Display caption, image number, and closing button. 412 Lightbox.prototype.updateDetails = function() { 413 var self = this; 414 415 // Enable anchor clicks in the injected caption html. 416 // Thanks Nate Wright for the fix. @https://github.com/NateWr 417 if (typeof this.album[this.currentImageIndex].title !== 'undefined' && 418 this.album[this.currentImageIndex].title !== '') { 419 var $caption = this.$lightbox.find('.lb-caption'); 420 if (this.options.sanitizeTitle) { 421 $caption.text(this.album[this.currentImageIndex].title); 422 } else { 423 $caption.html(this.album[this.currentImageIndex].title); 424 } 425 $caption.fadeIn('fast') 426 .find('a').on('click', function(event) { 427 if ($(this).attr('target') !== undefined) { 428 window.open($(this).attr('href'), $(this).attr('target')); 429 } else { 430 location.href = $(this).attr('href'); 431 } 432 }); 433 } 434 435 if (this.album.length > 1 && this.options.showImageNumberLabel) { 436 var labelText = this.imageCountLabel(this.currentImageIndex + 1, this.album.length); 437 this.$lightbox.find('.lb-number').text(labelText).fadeIn('fast'); 438 } else { 439 this.$lightbox.find('.lb-number').hide(); 440 } 441 442 this.$outerContainer.removeClass('animating'); 443 444 this.$lightbox.find('.lb-dataContainer').fadeIn(this.options.resizeDuration, function() { 445 return self.sizeOverlay(); 446 }); 447 }; 448 449 // Preload previous and next images in set. 450 Lightbox.prototype.preloadNeighboringImages = function() { 451 if (this.album.length > this.currentImageIndex + 1) { 452 var preloadNext = new Image(); 453 preloadNext.src = this.album[this.currentImageIndex + 1].link; 454 } 455 if (this.currentImageIndex > 0) { 456 var preloadPrev = new Image(); 457 preloadPrev.src = this.album[this.currentImageIndex - 1].link; 458 } 459 }; 460 461 Lightbox.prototype.enableKeyboardNav = function() { 462 $(document).on('keyup.keyboard', $.proxy(this.keyboardAction, this)); 463 }; 464 465 Lightbox.prototype.disableKeyboardNav = function() { 466 $(document).off('.keyboard'); 467 }; 468 469 Lightbox.prototype.keyboardAction = function(event) { 470 var KEYCODE_ESC = 27; 471 var KEYCODE_LEFTARROW = 37; 472 var KEYCODE_RIGHTARROW = 39; 473 474 var keycode = event.keyCode; 475 var key = String.fromCharCode(keycode).toLowerCase(); 476 if (keycode === KEYCODE_ESC || key.match(/x|o|c/)) { 477 this.end(); 478 } else if (key === 'p' || keycode === KEYCODE_LEFTARROW) { 479 if (this.currentImageIndex !== 0) { 480 this.changeImage(this.currentImageIndex - 1); 481 } else if (this.options.wrapAround && this.album.length > 1) { 482 this.changeImage(this.album.length - 1); 483 } 484 } else if (key === 'n' || keycode === KEYCODE_RIGHTARROW) { 485 if (this.currentImageIndex !== this.album.length - 1) { 486 this.changeImage(this.currentImageIndex + 1); 487 } else if (this.options.wrapAround && this.album.length > 1) { 488 this.changeImage(0); 489 } 490 } 491 }; 492 493 // Closing time. :-( 494 Lightbox.prototype.end = function() { 495 this.disableKeyboardNav(); 496 $(window).off('resize', this.sizeOverlay); 497 this.$lightbox.fadeOut(this.options.fadeDuration); 498 this.$overlay.fadeOut(this.options.fadeDuration); 499 $('select, object, embed').css({ 500 visibility: 'visible' 501 }); 502 if (this.options.disableScrolling) { 503 $('body').removeClass('lb-disable-scrolling'); 504 } 505 }; 506 507 return new Lightbox(); 508 }));