I'm new to JavaScript, and I've built a lightbox for an image gallery. There's a button to open the gallery, plus forwards, backwards, and close buttons, and keyboard controls. Currently, everything works exactly the way I intended, but I know that it can be more DRY, and would love some feedback on that.
Here is the relevant HTML for the image container:
<div class="gallery" data-image-source="img/gallery/project_main/1_IntegratedFarming.jpg">
<button class="secondary">
<i class="icon-gallery"></i>
<span>View Gallery</span>
</button>
</div>
And this is the JavaScript:
var fillGalleryContainers = function() {
$(".gallery").each(function(){
$(this).css("background-image", "url('" + $(this).attr("data-image-source") + "')");
});
};
var generateLightbox = function() {
var $lightboxOverlayHTML = $('<div id="overlay"></div>');
var $lightboxImageActiveHTML = $('<img class="gallery-image--active">');
var $lightboxImageNextHTML = $('<img class="gallery-image--next">');
var $logoPCLHTML = $('<i class="icon-pcl" id="logoPCL"></i>');
var $logoCommunityHTML = $('<i class="icon-community-alt" id="logoCommunity"></i>');
var $closeGalleryHTML = $('<i class="icon-close" id="closeGallery"></i>');
var $navNextHTML = $('<i class="icon-arrow-right" id="navNext"></i>');
var $navPrevHTML = $('<i class="icon-arrow-left" id="navPrev"></i>');
$lightboxOverlayHTML.append(
$lightboxImageActiveHTML,
$lightboxImageNextHTML,
$logoPCLHTML,
$logoCommunityHTML,
$navPrevHTML,
$navNextHTML,
$closeGalleryHTML
);
$('body').append($lightboxOverlayHTML);
};
var openLightbox = function() {
$('.gallery button').click(function(event){
var imageSource = $(this).parent().css("background-image");
var $lightboxOverlay = $('#overlay');
var $lightboxImageActive = $('.gallery-image--active');
var $lightboxImageNext = $('.gallery-image--next');
window.currentOverflow = $("html").css("overflow");
imageSource = imageSource.replace('url(', '').replace(')','');
$lightboxImageActive.attr("src", imageSource);
$lightboxOverlay.css({
top: $(window).scrollTop(),
left: $(window).scrollLeft()
});
$lightboxOverlay.fadeIn(1000);
$('html').css("overflow", "hidden");
});
};
var closeLightBox = function() {
$('#overlay').fadeOut(1000);
$("html").css("overflow", window.currentOverflow);
};
var galleryNavigationNext = function() {
var $activeImage = $('.gallery-image--active');
var $nextImage = $('.gallery-image--next');
var galleryImages = window.galleryImages;
var galleryTotal = galleryImages.length;
var location = window.location.href;
var currentImageSource = $activeImage.attr('src');
var modImageSource = currentImageSource.replace(location, '');
var currentPosition = $.inArray(modImageSource, galleryImages);
if (currentPosition < 0 ) {
currentPosition = 0;
}
var next = (currentPosition + 1 < galleryImages.length - 1) ? currentPosition + 1 : 0;
$nextImage.attr('src', galleryImages[next]);
$activeImage.fadeOut(1000, function() {
$activeImage.removeClass('gallery-image--active').addClass('remove');
$nextImage.addClass('gallery-image--active').removeClass('gallery-image--next');
$('.remove').remove();
$('.gallery-image--active').after('<img class="gallery-image--next">');
});
};
var galleryNavigationPrev = function() {
var $activeImage = $('.gallery-image--active');
var $nextImage = $('.gallery-image--next');
var galleryImages = window.galleryImages;
var galleryTotal = galleryImages.length;
var location = window.location.href;
var currentImageSource = $activeImage.attr('src');
var modImageSource = currentImageSource.replace(location, '');
var currentPosition = $.inArray(modImageSource, galleryImages);
if (currentPosition < 0 ) {
currentPosition = 0;
}
var next = (currentPosition - 1 >= 0) ? currentPosition - 1 : galleryImages.length - 1;
$nextImage.attr('src', galleryImages[next]);
$activeImage.fadeOut(1000, function() {
$activeImage.removeClass('gallery-image--active').addClass('remove');
$nextImage.addClass('gallery-image--active').removeClass('gallery-image--next');
$('.remove').remove();
$('.gallery-image--active').after('<img class="gallery-image--next">');
});
};
var galleryEvents = function() {
// Close Events
$('#closeGallery').click(closeLightBox);
$(document.documentElement).keyup(function(e){
if (event.keyCode == 88 || event.keyCode == 27) {
closeLightBox();
}
});
// Open Events
// Previous Events
$('#navPrev').click(galleryNavigationPrev);
$(document.documentElement).keyup(function(e){
if (event.keyCode == 37) {
galleryNavigationPrev();
}
});
// Next Events
$('#navNext').click(galleryNavigationNext);
$(document.documentElement).keyup(function(e){
if (event.keyCode == 39 || event.keyCode == 32) {
galleryNavigationNext();
}
});
};
Here is how the galleryImages
array gets populated (which will be populated via Wordpress). It's just an inline script at the bottom of the page.
<script>
window.galleryImages = [
"img/gallery/project_main/1_IntegratedFarming.jpg",
"img/gallery/project_main/2_BuildaCity.jpg",
"img/gallery/project_main/3_LearningCenter.jpg",
"img/gallery/project_main/4_CommonGrounds.jpg",
"img/gallery/project_main/project_main_gallery01.jpg",
"img/gallery/project_main/project_main_gallery02.jpg",
"img/gallery/project_main/project_main_gallery03.jpg",
"img/gallery/project_main/project_main_gallery04.jpg",
"img/gallery/project_main/project_main_gallery05.jpg",
"img/gallery/project_main/project_main_gallery06.jpg",
"img/gallery/project_main/project_main_gallery07.jpg",
"img/gallery/project_main/project_main_gallery08.jpg",
"img/gallery/project_main/project_main_gallery09.jpg",
];
</script>
I know that the galleryNavigationNext
and previous functions can be combined, but I'm not quite sure how passing variables from functional calls works. I've tried the below and it didn't work:
var galleryNavigation = function(direction) {
var $activeImage = $('.gallery-image--active');
var $nextImage = $('.gallery-image--next');
var galleryImages = window.galleryImages;
var galleryTotal = galleryImages.length;
var location = window.location.href;
var currentImageSource = $activeImage.attr('src');
var modImageSource = currentImageSource.replace(location, '');
var currentPosition = $.inArray(modImageSource, galleryImages);
if (currentPosition < 0 ) {
currentPosition = 0;
}
var next;
if (direction === "next") {
next = (currentPosition + 1 < galleryImages.length - 1) ? currentPosition + 1 : 0;
} else if (direction === "prev") {
next = (currentPosition - 1 >= 0) ? currentPosition - 1 : galleryImages.length - 1;
}
$nextImage.attr('src', galleryImages[next]);
$activeImage.fadeOut(1000, function() {
$activeImage.removeClass('gallery-image--active').addClass('remove');
$nextImage.addClass('gallery-image--active').removeClass('gallery-image--next');
$('.remove').remove();
$('.gallery-image--active').after('<img class="gallery-image--next">');
});
};
var galleryEvents = function() {
$('#navPrev').click(galleryNavigation("prev"));
$(document.documentElement).keyup(function(e){
if (event.keyCode == 37) {
galleryNavigation("prev");
}
});
$('#navNext').click(galleryNavigation("next"));
$(document.documentElement).keyup(function(e){
if (event.keyCode == 39 || event.keyCode == 32) {
galleryNavigation("next");
}
});
};