PageSourceSearch

https://www.dpj.co.jp/js/lightbox.js

js dpj.co.jp collected 2026-10-05 11:40:17 UTC 18,992 bytes, 520 lines download raw bytes

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

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.