lightbox2
Version:
The original Lightbox script. Uses jQuery.
1 lines • 14.6 kB
JavaScript
(function(root,factory){if(typeof define==="function"&&define.amd){define(["jquery"],factory)}else if(typeof exports==="object"){module.exports=factory(require("jquery"))}else{root.lightbox=factory(root.jQuery)}})(this,function($){function Lightbox(options){this.album=[];this.currentImageIndex=undefined;this._preloader=null;this._sizeOverlayProxy=null;this.$triggerElement=null;this.init();this.options=$.extend({},this.constructor.defaults);this.option(options)}Lightbox.defaults={albumLabel:"Image %1 of %2",alwaysShowNavOnTouchDevices:false,fadeDuration:600,fitImagesInViewport:true,imageFadeDuration:600,positionFromTop:50,resizeDuration:700,showImageNumberLabel:true,wrapAround:false,disableScrolling:false,sanitizeTitle:false};Lightbox.prototype.option=function(options){$.extend(this.options,options)};Lightbox.prototype.imageCountLabel=function(currentImageNum,totalImages){return this.options.albumLabel.replace(/%1/g,currentImageNum).replace(/%2/g,totalImages)};Lightbox.prototype.init=function(){var self=this;$(document).ready(function(){self.enable();self.build()})};Lightbox.prototype.enable=function(){var self=this;$("body").on("click.lightbox","a[rel^=lightbox], area[rel^=lightbox], a[data-lightbox], area[data-lightbox]",function(event){self.start($(event.currentTarget));return false})};Lightbox.prototype.build=function(){if($("#lightbox").length>0){return}var self=this;$('<div id="lightboxOverlay" tabindex="-1" class="lightboxOverlay"></div><div id="lightbox" tabindex="-1" class="lightbox" role="dialog" aria-modal="true" aria-label="Image lightbox"><div class="lb-outerContainer"><div class="lb-container"><img class="lb-image" src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" alt="" aria-describedby="lb-caption"/><div class="lb-nav"><a class="lb-prev" role="button" tabindex="0" aria-label="Previous image"></a><a class="lb-next" role="button" tabindex="0" aria-label="Next image"></a></div><div class="lb-loader"><a class="lb-cancel" role="button" tabindex="0"></a></div></div></div><div class="lb-dataContainer"><div class="lb-data"><div class="lb-details"><span id="lb-caption" class="lb-caption"></span><span class="lb-number" aria-live="polite"></span></div><div class="lb-closeContainer"><a class="lb-close" role="button" tabindex="0"></a></div></div></div></div>').appendTo($("body"));this.$lightbox=$("#lightbox");this.$overlay=$("#lightboxOverlay");this.$outerContainer=this.$lightbox.find(".lb-outerContainer");this.$container=this.$lightbox.find(".lb-container");this.$image=this.$lightbox.find(".lb-image");this.$nav=this.$lightbox.find(".lb-nav");this.$prev=this.$lightbox.find(".lb-prev");this.$next=this.$lightbox.find(".lb-next");this.$loader=this.$lightbox.find(".lb-loader");this.$dataContainer=this.$lightbox.find(".lb-dataContainer");this.$caption=this.$lightbox.find(".lb-caption");this.$number=this.$lightbox.find(".lb-number");this.$close=this.$lightbox.find(".lb-close");this.containerPadding={top:parseInt(this.$container.css("padding-top"),10),right:parseInt(this.$container.css("padding-right"),10),bottom:parseInt(this.$container.css("padding-bottom"),10),left:parseInt(this.$container.css("padding-left"),10)};this.imageBorderWidth={top:parseInt(this.$image.css("border-top-width"),10),right:parseInt(this.$image.css("border-right-width"),10),bottom:parseInt(this.$image.css("border-bottom-width"),10),left:parseInt(this.$image.css("border-left-width"),10)};this.$overlay.hide().on("click",function(){self.end();return false});this.$lightbox.hide().on("click",function(event){if($(event.target).attr("id")==="lightbox"){self.end()}});this.$outerContainer.on("click",function(event){if($(event.target).attr("id")==="lightbox"){self.end()}return false});this.$prev.on("click",function(event){event.preventDefault();if(self.currentImageIndex===0){self.changeImage(self.album.length-1)}else{self.changeImage(self.currentImageIndex-1)}});this.$next.on("click",function(event){event.preventDefault();if(self.currentImageIndex===self.album.length-1){self.changeImage(0)}else{self.changeImage(self.currentImageIndex+1)}});this.$nav.on("mousedown",function(event){if(event.which===3){self.$nav.css("pointer-events","none");self.$lightbox.one("contextmenu",function(){setTimeout(function(){self.$nav.css("pointer-events","auto")},0)})}});this.$loader.add(this.$close).on("click keyup",function(e){if(e.type==="click"||e.type==="keyup"&&(e.which===13||e.which===32)){self.end();return false}})};Lightbox.prototype.start=function($link){var self=this;this.$triggerElement=$link;this.album=[];var imageNumber=0;function addToAlbum($link){self.album.push({alt:$link.attr("data-alt"),link:$link.attr("href"),title:$link.attr("data-title")||$link.attr("title")})}var dataLightboxValue=$link.attr("data-lightbox");var $links;if(dataLightboxValue){$links=$($link.prop("tagName")).filter(function(){return $(this).attr("data-lightbox")===dataLightboxValue});for(var i=0;i<$links.length;i++){addToAlbum($($links[i]));if($links[i]===$link[0]){imageNumber=i}}}else{if($link.attr("rel")==="lightbox"){addToAlbum($link)}else{var relValue=$link.attr("rel");$links=$($link.prop("tagName")).filter(function(){return $(this).attr("rel")===relValue});for(var j=0;j<$links.length;j++){addToAlbum($($links[j]));if($links[j]===$link[0]){imageNumber=j}}}}this.$lightbox.css({top:this.options.positionFromTop+"px",left:"0px"}).fadeIn(this.options.fadeDuration);if(this.options.disableScrolling){$("body").addClass("lb-disable-scrolling")}this.$lightbox.on("keydown.focustrap",$.proxy(this._trapFocus,this));this.$overlay.on("keydown.focustrap",$.proxy(this._trapFocus,this));this.changeImage(imageNumber);$(document).trigger("lightbox:open",[{album:this.album,currentImageIndex:imageNumber}])};Lightbox.prototype.changeImage=function(imageNumber){var self=this;var filename=this.album[imageNumber].link;var filetype=filename.split("?")[0].split("#")[0].split(".").slice(-1)[0];this.disableKeyboardNav();this.$overlay.fadeIn(this.options.fadeDuration);this.$loader.fadeIn("slow");this.$image.hide();this.$nav.hide();this.$prev.hide();this.$next.hide();this.$dataContainer.hide();this.$number.hide();this.$caption.hide();this.$outerContainer.addClass("animating");if(this._preloader){this._preloader.onload=null;this._preloader.onerror=null}var preloader=new Image;this._preloader=preloader;preloader.onload=function(){if(preloader!==self._preloader){return}var imageHeight;var imageWidth;var maxImageHeight;var maxImageWidth;var windowHeight;var windowWidth;self.$image.attr({alt:self.album[imageNumber].alt,src:filename});self.$image.width(preloader.width);self.$image.height(preloader.height);var aspectRatio=preloader.width/preloader.height;windowWidth=$(window).width();windowHeight=$(window).height();maxImageWidth=windowWidth-self.containerPadding.left-self.containerPadding.right-self.imageBorderWidth.left-self.imageBorderWidth.right-20;maxImageHeight=windowHeight-self.containerPadding.top-self.containerPadding.bottom-self.imageBorderWidth.top-self.imageBorderWidth.bottom-self.options.positionFromTop-70;if(filetype==="svg"){if(aspectRatio>=1){imageWidth=maxImageWidth;imageHeight=parseInt(maxImageWidth/aspectRatio,10)}else{imageWidth=parseInt(maxImageHeight/aspectRatio,10);imageHeight=maxImageHeight}self.$image.width(imageWidth);self.$image.height(imageHeight)}else{if(self.options.fitImagesInViewport){if(self.options.maxWidth&&self.options.maxWidth<maxImageWidth){maxImageWidth=self.options.maxWidth}if(self.options.maxHeight&&self.options.maxHeight<maxImageHeight){maxImageHeight=self.options.maxHeight}}else{maxImageWidth=self.options.maxWidth||preloader.width||maxImageWidth;maxImageHeight=self.options.maxHeight||preloader.height||maxImageHeight}if(preloader.width>maxImageWidth||preloader.height>maxImageHeight){if(preloader.width/maxImageWidth>preloader.height/maxImageHeight){imageWidth=maxImageWidth;imageHeight=parseInt(preloader.height/(preloader.width/imageWidth),10);self.$image.width(imageWidth);self.$image.height(imageHeight)}else{imageHeight=maxImageHeight;imageWidth=parseInt(preloader.width/(preloader.height/imageHeight),10);self.$image.width(imageWidth);self.$image.height(imageHeight)}}}self.sizeContainer(self.$image.width(),self.$image.height())};preloader.onerror=function(){if(preloader!==self._preloader){return}self.$loader.stop(true).hide();self.$outerContainer.removeClass("animating");self.enableKeyboardNav()};preloader.src=this.album[imageNumber].link;this.currentImageIndex=imageNumber};Lightbox.prototype.sizeOverlay=function(){};Lightbox.prototype.sizeContainer=function(imageWidth,imageHeight){var self=this;var oldWidth=this.$outerContainer.outerWidth();var oldHeight=this.$outerContainer.outerHeight();var newWidth=imageWidth+this.containerPadding.left+this.containerPadding.right+this.imageBorderWidth.left+this.imageBorderWidth.right;var newHeight=imageHeight+this.containerPadding.top+this.containerPadding.bottom+this.imageBorderWidth.top+this.imageBorderWidth.bottom;function postResize(){self.$dataContainer.width(newWidth);self.$prev.height(newHeight);self.$next.height(newHeight);self.$overlay.trigger("focus");self.showImage()}if(oldWidth!==newWidth||oldHeight!==newHeight){this.$outerContainer.animate({width:newWidth,height:newHeight},this.options.resizeDuration,"swing",function(){postResize()})}else{postResize()}};Lightbox.prototype.showImage=function(){this.$loader.stop(true).hide();this.$image.fadeIn(this.options.imageFadeDuration);this.updateNav();this.updateDetails();this.preloadNeighboringImages();this.enableKeyboardNav();$(document).trigger("lightbox:change",[{album:this.album,currentImageIndex:this.currentImageIndex}])};Lightbox.prototype.updateNav=function(){var alwaysShowNav=false;try{document.createEvent("TouchEvent");alwaysShowNav=this.options.alwaysShowNavOnTouchDevices?true:false}catch(ignore){}this.$nav.show();if(this.album.length>1){if(this.options.wrapAround){if(alwaysShowNav){this.$prev.css("opacity","1");this.$next.css("opacity","1")}this.$prev.show();this.$next.show()}else{if(this.currentImageIndex>0){this.$prev.show();if(alwaysShowNav){this.$prev.css("opacity","1")}}if(this.currentImageIndex<this.album.length-1){this.$next.show();if(alwaysShowNav){this.$next.css("opacity","1")}}}}};Lightbox.prototype.updateDetails=function(){if(typeof this.album[this.currentImageIndex].title!=="undefined"&&this.album[this.currentImageIndex].title!==""){if(this.options.sanitizeTitle){this.$caption.text(this.album[this.currentImageIndex].title)}else{this.$caption.html(this.album[this.currentImageIndex].title)}this.$caption.fadeIn("fast")}if(this.album.length>1&&this.options.showImageNumberLabel){var labelText=this.imageCountLabel(this.currentImageIndex+1,this.album.length);this.$number.text(labelText).fadeIn("fast")}else{this.$number.hide()}this.$outerContainer.removeClass("animating");this.$dataContainer.fadeIn(this.options.resizeDuration)};Lightbox.prototype.preloadNeighboringImages=function(){if(this.album.length>this.currentImageIndex+1){var preloadNext=new Image;preloadNext.src=this.album[this.currentImageIndex+1].link}if(this.currentImageIndex>0){var preloadPrev=new Image;preloadPrev.src=this.album[this.currentImageIndex-1].link}};Lightbox.prototype.enableKeyboardNav=function(){this.$lightbox.on("keyup.keyboard",$.proxy(this.keyboardAction,this));this.$overlay.on("keyup.keyboard",$.proxy(this.keyboardAction,this))};Lightbox.prototype.disableKeyboardNav=function(){this.$lightbox.off(".keyboard");this.$overlay.off(".keyboard")};Lightbox.prototype.keyboardAction=function(event){var KEYCODE_ESC=27;var KEYCODE_LEFTARROW=37;var KEYCODE_RIGHTARROW=39;var keycode=event.keyCode;if(keycode===KEYCODE_ESC){event.stopPropagation();this.end()}else if(keycode===KEYCODE_LEFTARROW){if(this.currentImageIndex!==0){this.changeImage(this.currentImageIndex-1)}else if(this.options.wrapAround&&this.album.length>1){this.changeImage(this.album.length-1)}}else if(keycode===KEYCODE_RIGHTARROW){if(this.currentImageIndex!==this.album.length-1){this.changeImage(this.currentImageIndex+1)}else if(this.options.wrapAround&&this.album.length>1){this.changeImage(0)}}};Lightbox.prototype._trapFocus=function(event){if(event.keyCode!==9){return}var focusable=this.$lightbox.find("[tabindex]:visible").filter(function(){return parseInt($(this).attr("tabindex"),10)>=0});if(focusable.length===0){return}var first=focusable.first()[0];var last=focusable.last()[0];var active=document.activeElement;if(event.shiftKey){if(active===first||active===this.$lightbox[0]||active===this.$overlay[0]){event.preventDefault();last.focus()}}else{if(active===last){event.preventDefault();first.focus()}}};Lightbox.prototype.end=function(){this.disableKeyboardNav();this.$lightbox.off(".focustrap");this.$overlay.off(".focustrap");this.$lightbox.fadeOut(this.options.fadeDuration);this.$overlay.fadeOut(this.options.fadeDuration);if(this.options.disableScrolling){$("body").removeClass("lb-disable-scrolling")}if(this._preloader){this._preloader.onload=null;this._preloader.onerror=null;this._preloader=null}if(this.$triggerElement){this.$triggerElement.trigger("focus");this.$triggerElement=null}$(document).trigger("lightbox:close")};Lightbox.prototype.open=function(images,startIndex){startIndex=startIndex||0;this.album=[];if(typeof images==="string"){images=[{link:images}]}for(var i=0;i<images.length;i++){var img=typeof images[i]==="string"?{link:images[i]}:images[i];this.album.push({link:img.link||img.src||img.href,alt:img.alt||"",title:img.title||""})}if(this.album.length===0){return}this.$lightbox.css({top:this.options.positionFromTop+"px",left:"0px"}).fadeIn(this.options.fadeDuration);if(this.options.disableScrolling){$("body").addClass("lb-disable-scrolling")}this.$lightbox.on("keydown.focustrap",$.proxy(this._trapFocus,this));this.$overlay.on("keydown.focustrap",$.proxy(this._trapFocus,this));this.changeImage(startIndex);$(document).trigger("lightbox:open",[{album:this.album,currentImageIndex:startIndex}])};Lightbox.prototype.close=function(){this.end()};Lightbox.prototype.next=function(){if(this.currentImageIndex!==this.album.length-1){this.changeImage(this.currentImageIndex+1)}else if(this.options.wrapAround&&this.album.length>1){this.changeImage(0)}};Lightbox.prototype.prev=function(){if(this.currentImageIndex!==0){this.changeImage(this.currentImageIndex-1)}else if(this.options.wrapAround&&this.album.length>1){this.changeImage(this.album.length-1)}};Lightbox.prototype.destroy=function(){this.end();$("body").off("click.lightbox");if(this.$lightbox){this.$lightbox.remove()}if(this.$overlay){this.$overlay.remove()}};return new Lightbox});