A bit of an architectural question…
I originally created a Javascript singleton to house methods needed to operate a photo gallery module in a template file for a CMS system. The original specification only called for one instance of this photo gallery module on a page. (The code below is a gross simplification of what I actually wrote.)
Shortly after releasing the code, it dawned on me that even though the specification called for one instance of this module, this code would fall apart if a page had two instances of the module (i.e. the user adds two photo galleries to a page via the CMS). Now, the HTML markup is safe, because I used class names, but how would I go about restructuring my Javascript and jQuery event listeners to be able to handle multiple modules? You may assume that each photo gallery has its own JSON-P file (or you may assume a single JSON-P file if you think it can be handled more elegantly with one JSON-P file).
I think my original jQuery event listeners might have to be converted to $.delegate(), but I have no clue what to do after that and what to do about converting my singleton. Any leads would be appreciated. If you offer code, I prefer readability over optimization.
I’m not asking this question, because I have an immediate need to solve the problem for work. I am asking this question to be forward-thinking and to be a better Javascript developer, because I am expecting to run into this problem in the future and want to be prepared.
Thank you for reading.
HTML
<div class="photoGalleryMod">
<div class="photoGalleryImgBox"><img src="http://www.test.org/i/intro.jpg" alt="Intro Photo" /></div>
<div class="photoGalleryImgCap"><p>Caption</p></div>
<a href="#" class="photoGalleryPrevImgLnk"></a>
<a href="#" class="photoGalleryNextImgLnk"></a>
</div>
The Javascript is an external static file and makes a call to a JSON-P file via $.getSCript(), created by the CMS.
Javascript/jQuery
(function($) {
photoGalleryModule = {
json: '',
numSlidesInJson: '',
currentSlide: '',
updateSlide: function (arg_slidNum) {
/* Update the slide here */
},
init: function (arg_jsonObj) {
this.json = arg_jsonObj;
this.numSlidesInJson = this.json.photoGallerySlides.length;
this.currentSlide = 0;
}
};
$(document).ready(function() {
$.getScript('./photogallery.json');
$('.photoGalleryPrevImgLnk').live('click', function(event) {
photoGalleryModule.currentSlide = photoGalleryModule.currentSlide - 1;
photoGalleryModule.updateSlide(photoGalleryModule.currentSlide);
event.preventDefault();
});
$('.photoGalleryNextImgLnk').live('click', function(event) {
photoGalleryModule.currentSlide = photoGalleryModule.currentSlide + 1;
photoGalleryModule.updateSlide(photoGalleryModule.currentSlide);
event.preventDefault();
});
});
})(jQuery);
Contents of photo-gallery.json
photoGalleryModule.init(
{
photoGallerySlides:
[
{
type: 'intro',
pageTitle: 'Intro Photo',
imgUrl: 'http://www.test.org/i/intro.jpg',
imgAltAttr: 'Intro photo',
captionText: 'The intro photo',
},
{
type: 'normal',
pageTitle: 'First Photo',
imgUrl: 'http://www.test.org/i/img1.jpg',
imgAltAttr: 'First photo',
captionText: 'the first photo',
},
{
type: 'normal',
pageTitle: 'Second Photo',
imgUrl: 'http://www.test.org/i/img2.jpg',
imgAltAttr: 'Second photo',
captionText: 'the second photo',
}
]
});
I think the easiest way is to just turn your code into a plugin. So for the following HTML:
You would create the plugin with
$.fn.photoGallerywhere you pass in an index as a parameter:And then initiate each gallery like so:
Where you have the files
photogallery1.json,photogallery2.jsonandphotogallery3.jsonthat each invokemodule.init({ ... });with the necessary object data.