Skip to content

Instantly share code, notes, and snippets.

@baileylo
Created February 3, 2012 23:06
Show Gist options
  • Save baileylo/1733553 to your computer and use it in GitHub Desktop.
Save baileylo/1733553 to your computer and use it in GitHub Desktop.
First js in jquery - I did bad
/*
FILE ARCHIVED ON 9:31:31 Jan 3, 2010 AND RETRIEVED FROM THE
INTERNET ARCHIVE ON 23:03:13 Feb 3, 2012.
JAVASCRIPT APPENDED BY WAYBACK MACHINE, COPYRIGHT INTERNET ARCHIVE.
ALL OTHER CONTENT MAY ALSO BE PROTECTED BY COPYRIGHT (17 U.S.C.
SECTION 108(a)(3)).
*/
function Carousel(buffer_size, script, eventHandlerURL, user_variables, startingImage, displayImage, cookieName) {
/**
* List of the Current Images
* @var array
*/
var buffer = new Array(buffer_size);
/**
* Current Offset in the datdabase
* @var int
*/
var db_pointer = 0;
/**
* Size of the current database query
* @var array
*/
var db_size = 0;
/**
* Current Image being displayed
* @var int
*/
var int_ptr = 0;
/**
* Jquery object pointing to the location in the DOM where the main image is placed
* @var jquery
*/
var main_image = $('img[nameforjs=main_image]');
/**
* Jquery object pointing to the location in the DOM where the
* slding thumbnails are kept
* @var jquery
*/
var slideList = $('div[nameforjs=slidelist]');
/**
* SRC of the loading bar iamge
* @var string
*/
var load_image_url = main_image.attr('src');
/**
* Variable used to keep track of whether or not the @main_iamge has
* been hidden by a reset function call
* @var bool
*/
var hidden = false;
/**
* Used to differeinate between the desired buffer size, and the
* size that the database will allow, IE there are only 6 images
* in the query resultset, but hte buffer size was 10.
* @var int
*/
var max_buffer_size = buffer_size;
/**
* Prevents from grabbing another image on the far side of the buffer,
* while it is already retrieving one
* @var bool
*/
var fetchingImage= false;
/**
* Limits the active scrolling of the thumbnail list
* @var bool
*/
var sliderHoverScrolling = false;
/**
* List of Thumbnails that are currently being buffered
* @var array <Image>
*/
var buffering_tns = [];
/**
* Race condition signifying that the slider is is scrolling
* forwards
* @var bool
*/
var scrollForward = false;
/**
* Race condition signifying that the slider is is scrolling
* backwards
* @var bool
*/
var scrollBackwards = false;
/**
* Timeout create by the scrolling functions for the carousel slider.
* @var setTimeout
*/
var autoscrollTimeOut;
/**
* Checks to see if displayImage was passed in a function. If it wasn't
* it implements a very basic, not very scalable function to work as a basic
* display function
*/
if (typeof displayImage !== 'function') {
displayImage = function(image_data, main_image) {
main_image.fadeOut(1000, function() {
main_image.attr('src', image_data.image.src);
main_image.attr('alt', image_data.image.alt);
});
$("#image_title").html(image_data.title);
main_image.fadeIn(1000);
return;
};
}
/* EVENT HANDLERS */
/**
* Loads the Next Image.
*/
$('[nameforjs=nextImage]').click(function() {
/**
* Stop slider from scrolling
*/
clearTimeout(autoscrollTimeOut);
/**
* If there is another image, set the slider to display it
* Change the large image to the selected image, and save
* the event
*/
if (getOneImage('next') !== false) {
animateSetSlider(int_ptr);
displayImage(buffer[int_ptr], main_image);
eventHandler();
}
});
/**
* Loads the previous Image.
*/
$('[nameforjs=prevImage]').click(function() {
/**
* Stop slider from scrolling
*/
clearTimeout(autoscrollTimeOut);
/**
* If there is another image, set the slider to display it
* Change the large image to the selected image, and save
* the event
*/
if (getOneImage('prev') !== false) {
animateSetSlider(int_ptr);
displayImage(buffer[int_ptr], main_image);
eventHandler();
}
});
/**
* Scrolls image carousel forward if it currently isn't
*/
$("[nameforjs=next]").click(function(){
if (scrollForward === false){
clearTimeout(autoscrollTimeOut);
scrollBackwards = false;
autoScrollForwards(300);
}
});
/**
* Scrolls iamge carousel backward if it currently isn't
*/
$("[nameforjs=prev]").click(function() {
if (scrollBackwards === false) {
clearTimeout(autoscrollTimeOut);
scrollForward = false;
autoScrollBackwards(300);
}
});
/**
* Scrolsl the slider Caoursel Forward slide_size pixels
* @param int
*/
var autoScrollForwards = function (slide_size) {
/**
* Let program know that we are scrolling forward
*/
scrollForward = true;
/**
* Size of each image in the carousel in pixels
* @var int
*/
var max_size = 0;
$("#carouselSlider > img").each(function() {
max_size += $(this).width() + 15;
});
/**
* left offset in pixels
* @var int
*/
var left = parseInt(slideList.css('left'));
/**
* Size of the DOM object that displays the thumbnails.
* @var int
*/
var width = parseInt($('#slidelistContainer').css('width'));
/**
* If the left offset and the width minus 100 are greater than the total size you're at the end of the list
*/
if (-left+ width -100 > max_size) {
return true;
}
/**
* If we are nto currently scrolling the thumbnail list(how are we here)
* And we are with in 900 pixels of the end of the current list of thumbnails
* get 10 more thumbnails from the server.
*/
if (sliderHoverScrolling === false && max_size - (-left + width) < 900) {
getThumbNails(10);
}
/**
* Shorten the left offset by five pixels;
*/
left -= 5;
slideList.css('left', (left) + 'px');
/**
* If the slide_size is 0, you're hit the end of the request scroll
* stop the animation, tell the script it's done scrolling and return fasle;
*/
if (slide_size <= 0) {
clearTimeout(autoscrollTimeOut);
scrollForward = false;
return false;
}
/**
* Semi recurssion, calling this function again.
*/
autoscrollTimeOut = setTimeout(function() { autoScrollForwards(slide_size - 5); }, 10);
return true;
};
/**
* Scrolsl the slider Caoursel Backward slide_size pixels
* this function is essentially the one above see the comments there
* @param int
*/
var autoScrollBackwards = function(slide_size) {
/**
* Let program know that we are scrolling forward
*/
scrollBackwards = true;
/**
* Calculate left offset if it is at zero, stay there we're at the front of the list.
*/
var left = parseInt(slideList.css('left'));
if (left >= 0) {
return true;//rewrite to get the last images size;
}
left += 5;
slideList.css('left', (left) + 'px');
if (slide_size <= 0) {
clearTimeout(autoscrollTimeOut);
scrollBackwards = false;
return false;
}
autoscrollTimeOut = setTimeout(function() { autoScrollBackwards(slide_size-5); }, 10);
return true;
};
/**
* Wrapper function for the jquery .post function but making sure that it is returning
* a JSON object.
*/
var postJSON = function(url, offset, limit, searchCriteria, callbackfunction) {
$.post(url, {
offset: offset,
size: limit,
uservars: searchCriteria,
justjson: 1
}, callbackfunction, "json");
};
/**
* Retrieve thumbnails from the server
* @param int number of thumbnails request
*/
var getThumbNails = function(number) {
/**
* If we have loaded all images from the database return
*/
if ($("#carouselSlider > img").length == db_size ) {
return true;
} else if ($("#carouselSlider > img").length + number > db_size) {
/**
* Adjust requested number so that we don't query past the end of the database.
*/
number = $("#carouselSlider > img").length - number;
}
/**
* If we are currently getting thumbnails don't get more
* other wise tell the server we're getting thumbnails
* and then execute the AJAX request.
*/
if (sliderHoverScrolling === false) {
sliderHoverScrolling = true;
postJSON(script, $("#carouselSlider > img").length, number, user_variables, getThumbsCB);
} else {
return false;
}
return true;
};
/**
* Primary call to the server for Image Load
* will happen upon instanitation of the Carousel Object as well as a refresh of it
* @param string determins if it's a reload or an instanitation
*/
var getImages = function(type) {
if (type && type == 'reload') {
postJSON(script, db_pointer, max_buffer_size, user_variables, getImagesCB);
return;
}
/**
* If there is a setup cookie try to read the data from it
*/
var data = $.cookie.read(cookieName);
if (data) {
user_variables = data;
$.cookie.remove(cookieName);
}
postJSON(script, db_pointer, max_buffer_size, user_variables, getImagesCB);
};
/**
* Advances the internal pointer to the next or previous position while
* adding an addition image from the database to the end of the buffer
* @param string
*/
var getOneImage = function(direction) {
/**
* try to load the next image
*/
if (direction == 'next') {
/**
* If we are less than half of the distance from the fron
* of the buffer increase the the int_ptr and do not require
* a function call.
*/
if (int_ptr < parseInt(buffer_size / 2) - 1) {
int_ptr++;
return true;
}
/**
* This variable is used by the call back functionality to determine
* where to store the new image in the buffer
*/
index = buffer_size-1;
/**
* Deals with a case where half of buffer is filled with data from a previous query
* this occure when you reach the end of a database. This should be adjusted
* to be dealt with ON the PHP side, it may currently be already
*/
if (parseInt(db_size) <= parseInt(int_ptr) + parseInt(1) + parseInt(db_pointer)) {
return false;
}
/**
* First part sees if we're at the end of a query
* second part makes sure that we are not at the end of the database
* and I believe this functionality has been removed
*/
if (parseInt(buffer_size) < parseInt(max_buffer_size) || parseInt(buffer_size) + parseInt(db_pointer) >= parseInt(db_size)) {
if (int_ptr < buffer_size - 1) {
int_ptr++;
return true;
} else {
return false;
}
}
/**
* If there is current an AJAX request branch here
* if we are 6 places away from the right side of the buffer
* return false. Other wise advanced the internal pointer
*/
if (fetchingImage) {
if (int_ptr > buffer_size -6) {
return false;
}
int_ptr++;
return true;
}
/**
* Prepare variables for the AJAX request results
*/
offset = db_pointer+buffer_size;
db_pointer++;
for (var i=0; i+1 < buffer_size; i++) {
buffer[i] = buffer[i+1];
}
} else {
/**
* If we are less than half of the distance from the end
* of the buffer decrease the the int_ptr and do not require
* a function call.
*/
if (int_ptr > parseInt(buffer_size / 2)) {
int_ptr--;
return true;
}
/**
* This variable is used by the call back functionality to determine
* where to store the new image in the buffer
*/
index = 0;
/**
* Deals with a case where half of buffer is filled with data from a previous query
* this occure when you reach the end of a database. This should be adjusted
* to be dealt with ON the PHP side, it may currently be already
*/
if (db_pointer === 0) {
if (int_ptr !== 0) {
int_ptr--;
return true;
} else {
return false;
}
}
/**
* If there is current an AJAX request branch here
* if we are 6 places away from the front of the buffer
* return false. Other wise decrament the internal pointer
*/
if (fetchingImage) {
if (int_ptr < buffer_size -6) {
return false;
}
int_ptr--;
return true;
}
/**
* Prepare variables for the AJAX request results
*/
offset = --db_pointer;
for (var idx=buffer_size; idx >= 0; idx--) {
buffer[idx+1] = buffer[idx];
}
}
/**
* Tell the script we're fetching an Image
* and then execute the AJAX request
*/
fetchingImage = true;
postJSON(script, offset, 1, user_variables, getOneImageCB);
/**
* I believe this is the part of the Depricated functionality
*/
if ((int_ptr === 0 && index === 0) || (int_ptr === buffer_size -1 && index === (buffer_size - 1))) {
main_image.attr('src', load_image_url);
return false;
} else {
return true;
}
};
/**
* Changes the main Image when a thumbnail is clicked on
*/
var displayImageFromTN = function() {
/**
* Since this is called by .click event $(this) represent the
* thumbnail that was clicked on.
*/
var display_tn = $(this);
/**
* Get the index in buffer of the image that was clicked on
*/
var index = getPtrFromImg_id(display_tn.attr('imgindex'));
/**
* If the index is currently in buffer and isn't on the outter ends
* than we animate teh slider to it and display the image, and save an event
*/
if (index !== false && index != buffer_size - 1 && index !== 0) {
animateSetSlider(index);
int_ptr = index;
displayImage( buffer[index], main_image);
eventHandler();
return;
} else {
/**
* Set main Image to loading bar
*/
main_image.attr('src', load_image_url);
/**
* Calcluate the number of images before selected thumbnail
*/
var limit = 0;
display_tn.prevAll().each(function(){
limit++;
});
/**
* Calculate the front offset of the buffer
*/
db_pointer = limit - parseInt(buffer_size / 2) - 1;
/**
* Attempt to set the buffer to laod around the middle of int_ptr
* other wise just load from zero.
*/
if (db_pointer <= 0) {
int_ptr = limit;
db_pointer = 0;
} else {
db_pointer++;
int_ptr = parseInt(buffer_size / 2);
}
/**
* Store event and execute AJAX request
*/
eventHandler();
postJSON(script, db_pointer, max_buffer_size, user_variables, displayImageFromTNCB);
}
};
/* JSON CALL BACK FUNCTIONS */
/**
* Call back frunction for display Image from Thumbnail
* Reloads buffer, and adds images to thumbnail list
* @param JSON string
*/
var displayImageFromTNCB = function(data) {
data = data.data;
var iterator = 0;
/**
* Reloading buffer
*/
for (var itr in data) {
data[itr].image = new Image();
data[itr].tn = new Image();
buffer[iterator] = data[itr];
buffer[iterator].image.src = buffer[iterator].image_src;
buffer[iterator].image.alt = buffer[iterator].image_alt;
iterator++;
}
/**
* Check to see if thumbnail is already saved to thumbnail list
* (probably one of the most import codes in this script)
*/
//var image_list = $("#carouselSlider > img");
for (var i = 0; i < buffer_size; i++) {
var already_created = false;
$("#carouselSlider > img").each(function(itr, image) {
if ($(image).attr('imgIndex') == buffer[i].rand_id) {
already_created = true;
return false;
}
return true;
});
if (already_created === false) {
addSlideList(buffer[i]);
}
}
/**
* Display image and set the slider to the current Image
* run a validation test to make sure we have correct data
*/
displayImage( buffer[int_ptr], main_image);
animateSetSlider(int_ptr);
};
/**
* Call back frunction for getOngeImage
* Stores data to the buffer where desired.
* @param JSON string
*/
var getOneImageCB = function(data) {
data = data.data;
image_data = data.shift();
/**
* preload image, and save to buffer, index is defined in the calling function
*/
buffer[index] = image_data;
buffer[index].image = new Image();
buffer[index].image.src = image_data.image_src;
buffer[index].image.alt = image_data.image_alt;
/**
* If adding to the end of buffeer check to see
* if that iamges thumbnail is already on the list
* it should be btw, This code could probably be removed.
*/
if (index == buffer_size-1) {
var already_created = false;
$("#carouselSlider > img").each(function(itr, image) {
if ($(image).attr('imgIndex') == buffer[index].rand_id) {
already_created = true;
return false;
}
return true;
});
if (already_created === false) {
addSlideList(buffer[index]);
}
}
/**
* Part of what I believe to be depircated functionality.
* should remove the brancha nd awlays run these lines
*/
if ((int_ptr === 0 && index === 0) || (int_ptr === buffer_size-1 && index === (buffer_size - 1))) {
animateSetSlider(int_ptr);
displayImage(buffer[int_ptr], main_image);
}
/**
* Tell the script we're done fetching one image,
* and then validate the thumbnail list
*/
fetchingImage = false;
};
/**
* Call back frunction for getThumbs
* Adds thumbnails to buffer
* @param JSON string
*/
var getThumbsCB = function(data) {
data = data.data;
/**
* beging to load image and display it on the slide show
*/
for (var itr in data) {
data[itr].tn = new Image();
data[itr].tn.src = data[itr].tn_src;
data[itr].tn.alt = data[itr].image_alt;
addSlideList(data[itr]);
}
/**
* tell script the AJAX request has finished
* validate the thumbnail list
*/
sliderHoverScrolling = false;
};
/**
* Generates the buffer from scratch
* @param JSON string
*/
var getImagesCB = function(data) {
/**
* Create buffer a new and reset the DBsize to the returned value
*/
buffer = new Array(max_buffer_size);
db_size = data.num_rows;
/**
* Check to see if there are no Images returned and
* display Error Message
*/
if (db_size === 0) {
var div = $(document.createElement('div'));
div.css('background', 'white');
div.css('width', '250px');
div.css('height', '250px');
div.css('border', '1px solid #ccc');
div.css('margin', '0 auto');
var header = $(document.createElement('h2'));
var paragraph = $(document.createElement('p'));
paragraph.html("No products were found matching your criteria.");
header.html("Sorry");
main_image.css('display', 'none');
$("#image").html("");
div.html(header).append(paragraph);
$("#image").append(div);
if ($("#image").next()) {
$("#image").next().css('display', 'none');
}
hidden = true;
return;
} else if(hidden === true) {
/**
* Check to see if we are returning from an error message
* and recreate the DOM objects needed to display the carousel
*/
reDrawImage();
$("#image").next().css('display', 'block');
}
/**
* Load data into buffer, and add the slide show to list
*/
var image_list = data.data;
for (var itr in image_list) {
image_list[itr].image = new Image();
image_list[itr].image.src = image_list[itr].image_src;
image_list[itr].image.alt = image_list[itr].image_alt;
image_list[itr].tn = new Image();
image_list[itr].tn.src = image_list[itr].tn_src;
image_list[itr].tn.alt = image_list[itr].image_alt;
buffer[int_ptr] = image_list[itr];
addSlideList(buffer[int_ptr]);
int_ptr++;
}
/**
* If the requested Size is's greater than the actual size
* set requested size to actual size
*/
if (db_size < max_buffer_size) {
buffer_size = db_size;
} else {
buffer_size = max_buffer_size;
}
/**
* We need to make sure that the PHP doesn't
* Think that we're still coming from a cookie
*/
var jsonObject = $.evalJSON(user_variables);
jsonObject.display_image = false;
user_variables = $.compactJSON(jsonObject);
/**
* Display main image and set the int_ptr to that image
* record the event and add the evnet handler onto the thumbanils
* than set the slider to display the correct thumbnail and validate thumbnail list
*/
displayImage(buffer[data.highlighted_image], main_image);
int_ptr = data.highlighted_image;
eventHandler();
$("#carouselSlider > img").click(displayImageFromTN);
setSlider(int_ptr);
};
/**
* Sets the slider to a specific image given it's index in the buffer
* @param int
*/
var setSlider = function(imgIndex) {
/**
* Sets the background of all thumbnails to black;
*/
$("#carouselSlider > img").each(function() {
$(this).css('background', 'white');
$(this).mouseover(function() { $(this).css({'background':'#A9A9A9'}); } );
$(this).mouseout(function() { $(this).css({'background':'white'}); } );
});
/**
* Locate image in slide show given it's envshot_id
* then set it's background to white so it stands out
*/
var current_image = $('img[imgindex=' + buffer[imgIndex].rand_id + ']');
current_image.css('background', '#0d88cf');
current_image.mouseover(function() { $(this).css({'background':'#0d88cf'}); });
current_image.mouseout(function() { $(this).css({'background':'#0d88cf'}); });
/**
* width of images preceding current image
* 7 represents the border padding and margin of thumbnails
*/
var scroll_size = 0;
$('img[imgindex=' + buffer[imgIndex].rand_id + ']').prevAll().each(function() {
scroll_size += $(this).width() + 7;
});
/**
* Set the left offset so that it correctly adjusts to the new image
*/
slideList.css('left', -scroll_size);
};
/**
* Sets the slider to a specific image given it's index in the buffer
* with a nice scrolling animation.
* @param int
*/
var animateSetSlider = function(imgIndex) {
/**
* Locate image in slide show given it's envshot_id
* calcuate the left offset to place the image in the middle
*/
var current_image = $('img[imgindex=' + buffer[imgIndex].rand_id + ']');
var width = parseInt(parseInt($("#slidelistContainer").css('width')) / 2);
var left_align = width - (current_image.width() / 2);
/**
* width of images preceding current image
* 15, 2px for L/R border 8px for L/R padding 5px for left margin
*/
scroll_size = 0;
current_image.prevAll().each(function() {
scroll_size -= $(this).width() + 15;
});
/**
* width of images after current image and including current image
* 15, 2px for L/R border 8px for L/R padding 5px for left margin
*/
var total_size = -scroll_size + current_image.width() + 15;
current_image.nextAll().each(function() {
total_size += $(this).width() + 15;
});
/**
* Calcuate teh scrolling in pixels require to center th image
*/
if (scroll_size >= 0 || -scroll_size < width) {
scroll_size = 0;
} else if (width + -scroll_size > total_size) {
scroll_size = -total_size + parseInt($("#slidelistContainer").css('width'));
} else {
scroll_size += left_align;
}
/**
* Sets the background of all thumbnails to black;
* then set current images backgrount to white
*/
$("#carouselSlider > img").each(function() {
$(this).css('background', 'white');
$(this).mouseover(function() { $(this).css({'background':'#A9A9A9'}); });
$(this).mouseout(function() { $(this).css({'background':'white'}); });
});
current_image.css('background', '#0d88cf');
current_image.mouseover(function() { $(this).css({'background':'#0d88cf'}); });
current_image.mouseout(function() { $(this).css({'background':'#0d88cf'}); });
/**
* User jquery animate functionality to move the slider to the correct position
* queue prevents multiple scrolls stacking on top of eachother, they will go off
* as teh come in and no longer wait for one to finish to start teh enxt
*/
slideList.animate({"left": scroll_size + "px"}, {duration: 500, queue: false});
return true;
};
/**
* Sets up the DOm to handle the carousel
*/
var reDrawImage = function() {
$('#image').html('<img nameforjs="main_image" src="' + load_image_url + '" />');
main_image = $("[nameforjs=main_image]");
};
/**
* Given an envshot_id looks up the id int he buffer.
* if it is not there returns false other wise returns the index
* @return int | bool
*/
var getPtrFromImg_id = function(img_id) {
for (var index in buffer) {
if (buffer[index].rand_id == img_id) {
return index;
}
}
return false;
};
/**
* Adds a thumbnail to the carousel slider
* @param image object
*/
var addSlideList = function(image) {
/**
* Having problems with these browsers
* and preloading the images
* so the images are just directly loaded
* to the browser
*/
var img = $( document.createElement('img') );
if ($.browser.msie) {
img.attr('src', image.tn_src);
img.attr('imgIndex', image.rand_id);
img.appendTo(slideList);
} else {
/**
* Being loadin the Image
*/
buffering_tns[image.rand_id]= new Image();
buffering_tns[image.rand_id].src = image.tn_src;
/**
* Add loading image to the thumbnail list
*/
img.attr('src', media_base + "/images/lightbox/loading.gif");
img.attr('width', "75");
img.attr('imgIndex', image.rand_id);
img.appendTo(slideList);
/**
* Create event so that we change out the load iamge
* with the real iamge upon completion of it's load
*/
$(buffering_tns[image.rand_id]).load(function() {
img.attr('src', buffering_tns[image.rand_id].src);
img.attr('width', buffering_tns[image.rand_id].width);
});
}
/**
* Add event handler to the thumbnail
*/
$("#carouselSlider > img").click(displayImageFromTN);
};
/**
* Stores information about the current image in the event holder
* on the server
*/
var eventHandler = function() {
$.post(eventHandlerURL, {id: buffer[int_ptr].rand_id, query_string: user_variables}, function(){});
var jsonObject = $.evalJSON(user_variables);
jsonObject.display_image = buffer[int_ptr].rand_id;
$.cookie.create(cookieName, $.compactJSON(jsonObject), 60);
};
/* This function call is needed to get things started */
getImages();
//Public Methods
return {
/**
* reloads variables to refresh the Carousel browsing window
*/
reloadCarousel: function(user_vars) {
db_pointer = 0;
db_size = 0;
int_ptr = 0;
user_variables = user_vars;
main_image.attr('src', load_image_url);
slideList.html(" ");
getImages('reload');
}
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment