(function(root, factory) { if (typeof define === 'function' && define.amd) { define([], factory); } else if (typeof module === 'object' && module.exports) { module.exports = factory(); } else { root.SimpleLightbox = factory(); } }(this, function() { function assign(target) { for (var i = 1; i < arguments.length; i++) { var obj = arguments[i]; if (obj) { for (var key in obj) { obj.hasOwnProperty(key) && (target[key] = obj[key]); } } } return target; } function addClass(element, className) { if (element && className) { element.className += ' ' + className; } } function removeClass(element, className) { if (element && className) { element.className = element.className.replace( new RegExp('(\\s|^)' + className + '(\\s|$)'), ' ' ).trim(); } } function parseHtml(html) { var div = document.createElement('div'); div.innerHTML = html.trim(); return div.childNodes[0]; } function matches(el, selector) { return (el.matches || el.matchesSelector || el.msMatchesSelector).call(el, selector); } function getWindowHeight() { return 'innerHeight' in window ? window.innerHeight : document.documentElement.offsetHeight; } function SimpleLightbox(options) { this.init.apply(this, arguments); } SimpleLightbox.defaults = { // add custom classes to lightbox elements elementClass: '', elementLoadingClass: 'slbLoading', htmlClass: 'slbActive', closeBtnClass: '', nextBtnClass: '', prevBtnClass: '', loadingTextClass: '', // customize / localize controls captions closeBtnCaption: 'Close', nextBtnCaption: 'Next', prevBtnCaption: 'Previous', loadingCaption: 'Loading...', bindToItems: true, // set click event handler to trigger lightbox on provided $items closeOnOverlayClick: true, closeOnEscapeKey: true, nextOnImageClick: true, showCaptions: true, captionAttribute: 'title', // choose data source for library to glean image caption from urlAttribute: 'href', // where to expect large image startAt: 0, // start gallery at custom index loadingTimeout: 100, // time after loading element will appear appendTarget: 'body', // append elsewhere if needed beforeSetContent: null, // convenient hooks for extending library behavoiur beforeClose: null, afterClose: null, beforeDestroy: null, afterDestroy: null, videoRegex: new RegExp(/youtube.com|vimeo.com/) // regex which tests load url for iframe content }; assign(SimpleLightbox.prototype, { init: function(options) { options = this.options = assign({}, SimpleLightbox.defaults, options); var self = this; var elements; if (options.$items) { elements = options.$items.get(); } if (options.elements) { elements = [].slice.call( typeof options.elements === 'string' ? document.querySelectorAll(options.elements) : options.elements ); } this.eventRegistry = {lightbox: [], thumbnails: []}; this.items = []; this.captions = []; if (elements) { elements.forEach(function(element, index) { self.items.push(element.getAttribute(options.urlAttribute)); self.captions.push(element.getAttribute(options.captionAttribute)); if (options.bindToItems) { self.addEvent(element, 'click', function(e) { e.preventDefault(); self.showPosition(index); }, 'thumbnails'); } }); } if (options.items) { this.items = options.items; } if (options.captions) { this.captions = options.captions; } }, addEvent: function(element, eventName, callback, scope) { this.eventRegistry[scope || 'lightbox'].push({ element: element, eventName: eventName, callback: callback }); element.addEventListener(eventName, callback); return this; }, removeEvents: function(scope) { this.eventRegistry[scope].forEach(function(item) { item.element.removeEventListener(item.eventName, item.callback); }); this.eventRegistry[scope] = []; return this; }, next: function() { return this.showPosition(this.currentPosition + 1); }, prev: function() { return this.showPosition(this.currentPosition - 1); }, normalizePosition: function(position) { if (position >= this.items.length) { position = 0; } else if (position < 0) { position = this.items.length - 1; } return position; }, showPosition: function(position) { var newPosition = this.normalizePosition(position); if (typeof this.currentPosition !== 'undefined') { this.direction = newPosition > this.currentPosition ? 'next' : 'prev'; } this.currentPosition = newPosition; return this.setupLightboxHtml() .prepareItem(this.currentPosition, this.setContent) .show(); }, loading: function(on) { var self = this; var options = this.options; if (on) { this.loadingTimeout = setTimeout(function() { addClass(self.$el, options.elementLoadingClass); self.$content.innerHTML = '
'; self.show(); }, options.loadingTimeout); } else { removeClass(this.$el, options.elementLoadingClass); clearTimeout(this.loadingTimeout); } }, prepareItem: function(position, callback) { var self = this; var url = this.items[position]; this.loading(true); if (this.options.videoRegex.test(url)) { callback.call(self, parseHtml( '') ); } else { var $imageCont = parseHtml( '' ); this.$currentImage = $imageCont.querySelector('.slbImage'); if (this.options.showCaptions && this.captions[position]) { $imageCont.appendChild(parseHtml( '