/*! * baguettebox.js * @author feimosi * @version 0.7.0 * @url https://github.com/feimosi/baguettebox.js */ var baguettebox = (function() { // svg shapes used in buttons var leftarrow = '', rightarrow = '', closex = ''; // main id names var overlayid = 'baguettebox-overlay'; var sliderid = 'baguettebox-slider'; // global options and their defaults var options = {}, defaults = { captions: true, buttons: 'auto', async: false, preload: 2, animation: 'slidein' }; // dom elements references var overlay, slider, previousbutton, nextbutton, closebutton; // current image index inside the slider and displayed gallery index var currentindex = 0, currentgallery = -1; // touch event start position (for slide gesture) var touchstartx; // if set to true ignore touch events because animation was already fired var touchflag = false; // array of all used galleries (dom elements) var galleries = []; // 2d array of galleries and images inside them var imagesmap = []; // array containing temporary images dom elements var imagesarray = []; // foreach polyfill for ie8 if(!array.prototype.foreach) { array.prototype.foreach = function(callback, thisarg) { var len = this.length; for(var i = 0; i < len; i++) { callback.call(thisarg, this[i], i, this); } }; } // script entry point function run(selector, useroptions) { buildoverlay(); // for each gallery bind a click event to every image inside it galleries = document.queryselectorall(selector); [].foreach.call( galleries, function (galleryelement, galleryindex) { var galleryid = imagesmap.length; imagesmap.push(galleryelement.getelementsbytagname('a')); imagesmap[galleryid].options = useroptions; [].foreach.call( imagesmap[galleryid], function (imageelement, imageindex) { bind(imageelement, 'click', function(event) { /*jshint -w030 */ event.preventdefault ? event.preventdefault() : event.returnvalue = false; prepareoverlay(galleryid); showoverlay(imageindex); }); } ); } ); defaults.transforms = testtransformssupport(); } function buildoverlay() { overlay = document.getelementbyid(overlayid); // check if the overlay already exists if(overlay) { slider = document.getelementbyid(sliderid); previousbutton = document.getelementbyid('previous-button'); nextbutton = document.getelementbyid('next-button'); closebutton = document.getelementbyid('close-button'); return; } // create overlay element overlay = document.createelement('div'); overlay.id = overlayid; document.getelementsbytagname('body')[0].appendchild(overlay); // create gallery slider element slider = document.createelement('div'); slider.id = sliderid; overlay.appendchild(slider); // create all necessary buttons previousbutton = document.createelement('button'); previousbutton.id = 'previous-button'; previousbutton.innerhtml = leftarrow; overlay.appendchild(previousbutton); nextbutton = document.createelement('button'); nextbutton.id = 'next-button'; nextbutton.innerhtml = rightarrow; overlay.appendchild(nextbutton); closebutton = document.createelement('button'); closebutton.id = 'close-button'; closebutton.innerhtml = closex; overlay.appendchild(closebutton); previousbutton.classname = nextbutton.classname = closebutton.classname = 'baguettebox-button'; bindevents(); } function bindevents() { // when clicked on the overlay (outside displayed image) close it bind(overlay, 'click', function(event) { if(event.target && event.target.nodename !== "img") hideoverlay(); }); // add event listeners for buttons bind(document.getelementbyid('previous-button'), 'click', function(event) { /*jshint -w030 */ event.stoppropagation ? event.stoppropagation() : event.cancelbubble = true; showpreviousimage(); }); bind(document.getelementbyid('next-button'), 'click', function(event) { /*jshint -w030 */ event.stoppropagation ? event.stoppropagation() : event.cancelbubble = true; shownextimage(); }); bind(document.getelementbyid('close-button'), 'click', function(event) { /*jshint -w030 */ event.stoppropagation ? event.stoppropagation() : event.cancelbubble = true; hideoverlay(); }); // add touch events bind(overlay, 'touchstart', function(event) { // save x axis position touchstartx = event.changedtouches[0].pagex; }); bind(overlay, 'touchmove', function(event) { if(touchflag) return; /*jshint -w030 */ event.preventdefault ? event.preventdefault() : event.returnvalue = false; touch = event.touches[0] || event.changedtouches[0]; if(touch.pagex - touchstartx > 40) { touchflag = true; showpreviousimage(); } else if (touch.pagex - touchstartx < -40) { touchflag = true; shownextimage(); } }); bind(overlay, 'touchend', function(event) { touchflag = false; }); // activate keyboard shortcuts bind(document, 'keydown', function(event) { switch(event.keycode) { case 37: // left arrow showpreviousimage(); break; case 39: // right arrow shownextimage(); break; case 27: // esc hideoverlay(); break; } }); } function prepareoverlay(galleryindex) { // if the same gallery is being opened prevent from loading it once again if(currentgallery === galleryindex) return; currentgallery = galleryindex; // update gallery specific options setoptions(imagesmap[galleryindex].options); // empty slider of previous contents (more effective than .innerhtml = "") while(slider.firstchild) slider.removechild(slider.firstchild); imagesarray.length = 0; // prepare and append images containers for(var i = 0; i < imagesmap[galleryindex].length; i++) { imagesarray.push(returnimagecontainer()); slider.appendchild(imagesarray[i]); } } function setoptions(newoptions) { if(!newoptions) newoptions = {}; for(var item in defaults) { options[item] = defaults[item]; if(typeof newoptions[item] !== 'undefined') options[item] = newoptions[item]; } /* apply new options */ // change transition for proper animation slider.style.transition = slider.style.webkittransition = options.animation === 'fadein' ? 'opacity .4s ease' : ''; // hide buttons if necessary if(options.buttons === 'auto' && ('ontouchstart' in window || imagesmap[currentgallery].length === 1)) options.buttons = false; // set buttons style to hide or display them previousbutton.style.display = nextbutton.style.display = options.buttons ? '' : 'none'; } // return dom element for image container