I am pulling multiple feeds from youtube that have a callback function which makes markup from each feed. They add that markup to a documentFragment stored in var data. When all the feeds have contributed what they should, a final callback runs. Each feed can deal with its own thumbnails and page menu, so it makes sense to get that started without waiting for all of the feeds to be done. Some markup requires all of them to be done, so I do that in the final callback. To complicate matters, the markup needs to be appended in an order dictated by the user and some sets of markup may need to be cloned if requested. This allows the user to easily build the plugin as they see fit. Here is the option for that.
build:['listsMenu', 'listTitle', 'listDesc', 'player', 'pageMenu', 'thumbnails']
or another possibility...something like this:
build:['player', 'listsMenu', 'pageMenu', 'thumbnails', 'pageMenu']
This is the best solution I have been able to come up with so far. Any suggestions are appreciated!
//in the function that makes the ajax calls -
data = {};
namespace.thumbs.prototype.feedCallback = function(context, options, data, optList, listNum, feed) {
if (options.build.indexOf('pageMenu') !== -1 || options.build.indexOf('thumbnails') !== -1) {
var feedVideosInPages = this.return_feedVideosInPages(options.thumbCount, options.thumbsPerPage, feed.videos);
var pagesMenu = this.return_PagesMenu(options, listNum, feedVideosInPages);
var thumbnails = this.return_thumbsMarkup(options, optList, listNum, feedVideosInPages);
data.pagesMenus = data.pagesMenus || document.createDocumentFragment();
data.thumbnails = data.thumbnails || document.createDocumentFragment();
if (pagesMenu) { data.pagesMenus.appendChild(pagesMenu); }
data.thumbnails.appendChild(thumbnails);
}
data.each = data.each || [];
data.each.push({'feed':feed, 'optList':optList, 'listNum':listNum});
if (data.each.length === options.lists.length) { this.allFeedsReady(context, options, data); }
};
namespace.thumbs.prototype.allFeedsReady = function(context, options, data) {
this.sort_dataEach(data);
elems = document.createDocumentFragment();
addedElemNames = [];
clonedElems = {};
toAdd = options.build.slice();
var buildLength = options.build.length;
for (var i=0; i<buildLength; ++i) {
var name = options.build[i];
if (addedElemNames.indexOf(name) === -1) { //this is the first time the element has been added.
switch (name) {
case 'pageMenu': elem = data.pagesMenus; break;
case 'thumbnails': elem = data.thumbnails; break;
case 'player': elem = this.return_playerDiv(context); break;
case 'listMenu': elem = this.return_listsMenuMarkup(data.each); break;
//case 'listTitle': elem = allData.markup.listsTitles[0]; break;
case 'listDesc': elem = this.return_listsDescsMarkup(data.each); break;
case 'videoTitle': elem = this.return_videoTitleMarkup(data.each); break;
default: elem = false;
}
addedElemNames.push(name);
}
else {
elem = clonedElems[name];
}
toAdd.splice(toAdd.indexOf(name), 1); //remove this item from array of things to be added
if (elem) {
if (toAdd.indexOf(name) !== -1) { clonedElems[name] = elem.cloneNode(true); }//the build will contain another copy, so clone it
elems.appendChild(elem);
}
}
context.appendChild(elems);
}