Created
February 3, 2011 21:36
-
-
Save jcontonio/810260 to your computer and use it in GitHub Desktop.
A jQuery based content slider for use with carousels and the like
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* HFCSlider | |
* | |
* @author Jay Contonio - jcontonio.com | |
* @constructor | |
* @example (as seen on @link:http://sabin.org/) | |
var settings = { | |
'controller': this, | |
'mask': this._carouselContainer.find('.thumbnails .mask'), | |
'container': this._carouselContainer.find('.thumbnails ol'), | |
'listItems': this._carouselContainer.find('.thumbnails li'), | |
'arrowClass': this._carouselContainer.find('.thumbnails .arrow'), | |
'wrapping': false, | |
'slidesPer': this._itemsPerPage, | |
'spacing': this._spacing | |
} | |
this._slider = new HFCSlider(settings); | |
// Move the slider two the second space | |
this._slider.move(1); | |
* @param {Object} settings The settings object includes the following params | |
* @param {String} controller The object that contains the slider, usually Application or Carousel | |
* @param {String} mask The mask div that contains the _container element you're moving around | |
* @param {String} listItems The list items that make up each item in the slider | |
* @param {String} arrowClass The previous and next arrows should have this class on them | |
* @param {Boolean} wrapper Should the carousel be an infinite loop | |
* @param {Number} slidesPer How many list items per slide (optional) | |
* @param {Number} spacing The margin between each item (optional) (usually used with slidesPer) | |
* @param {String} animationStyle Can be dissolve or slide (defaults to slide) | |
* @returns {Object} Returns itself | |
*/ | |
var HFCSlider = function(settings) | |
{ | |
this._object = settings['controller']; | |
this._mask = settings['mask']; | |
this._container = settings['container']; | |
this._listItems = settings['listItems']; | |
this._arrowClass = settings['arrowClass']; | |
this._wrap = settings['wrapping']; | |
this._slidesPer = settings['slidesPer'] === undefined ? 1 : settings['slidesPer']; | |
this._spacing = settings['spacing'] === undefined ? 0 : settings['spacing']; | |
this._animationStyle = settings['animationStyle'] === undefined ? 'slide' : settings['animationStyle']; | |
this._currentIndex = 0; | |
this._clickEvent = jQuery.Event("HFC_CAROUSEL_CLICK_EVENT"); | |
this._moveEvent = jQuery.Event("HFC_CAROUSEL_MOVED"); | |
// If the mask doesn't have a position of relateive|absolute yet, give it one | |
if ($(this._mask).css('position') === 'static') | |
{ | |
$(this._mask).css({ 'position':'relative' }); | |
} | |
// Set it's overflow-x to hidden | |
$(this._mask).css({ 'overflow-x':'hidden' }); | |
// Position the element we're moving to 0,0 | |
$(this._container).css({ 'position':'absolute', 'top':'0', 'left':'0' }); | |
this.init(); | |
return this; | |
} | |
/** | |
* Initializes the view | |
*/ | |
HFCSlider.prototype.init = function() | |
{ | |
if(this._wrap) this.createWrappingItem(); | |
// Set the number of slides | |
this._numSlides = this._listItems.length; | |
// Sets the container width to the width of each slide * the amount of slides. (should be very wide) | |
this._slideWidth = $(this._listItems[0]).width() + this._spacing; | |
this._container.width(this._numSlides * this._slideWidth); | |
this._slidesWidth = this._mask.width(); | |
// Override the number of slides if we are passed a slidesPer variable | |
// ie: if there are 3 slides per Slide | |
this._numSlides = Math.ceil(this._numSlides / this._slidesPer); | |
// Enable the arrows | |
this.enableArrows(); | |
// If wrapping is set to false, disable the previous arrow on start | |
if(!this._wrap) this.disableArrow('previous'); | |
} | |
/** | |
* @returns {Number} Returns the current index of the active slide (starting with 0) | |
* @type Number | |
*/ | |
HFCSlider.prototype.getCurrentIndex = function() | |
{ | |
return this._currentIndex; | |
} | |
/** | |
* Disables an arrow | |
* @param {String} arrow Disables the 'previous' or 'next' arrow | |
*/ | |
HFCSlider.prototype.disableArrow = function(arrow) | |
{ | |
$(this._arrowClass + '[href=#' + arrow + ']').css('cursor','default').addClass('disabled'); | |
} | |
/** | |
* Enables an arrow | |
* @param {String} arrow Enabled the 'previous' or 'next' arrow | |
*/ | |
HFCSlider.prototype.enableArrow = function(arrow) | |
{ | |
$(this._arrowClass + '[href=#' + arrow + ']').css('cursor','pointer').removeClass('disabled'); | |
} | |
/** | |
* Enables both arrows and assigns the click event | |
* @event 'HFC_CAROUSEL_CLICK_EVENT' Broadcasts this event | |
*/ | |
HFCSlider.prototype.enableArrows = function() | |
{ | |
var that = this; | |
this._arrowClass.unbind('click'); | |
$(this._arrowClass).click(function(e) { | |
e.preventDefault(); | |
$(this).attr('href') == "#previous" ? that.move('previous') : that.move('next'); | |
$(that._object).trigger(that._clickEvent); | |
return false; | |
}); | |
} | |
/** | |
* Disables both arrows by unbinding the click event | |
*/ | |
HFCSlider.prototype.disableArrows = function() | |
{ | |
this._arrowClass.unbind('click'); | |
this._arrowClass.click(function(e) { e.preventDefault(); }); | |
} | |
/** | |
* Duplicates the first item in the slider and appends it as the last | |
* Results in an infinite looping carousel | |
*/ | |
HFCSlider.prototype.createWrappingItem = function() | |
{ | |
this._listItems[0].clone().appendTo(this._container); | |
this._listItems.push(this._listItems[0]); | |
} | |
/** | |
* Moves the _container back, forward, or to a specific index | |
* @param {String} direction 'previous' or 'next' | |
* @param {Number} direction Can also be an index starting with 0 | |
*/ | |
HFCSlider.prototype.move = function(direction) | |
{ | |
var that = this; | |
switch(direction) | |
{ | |
case 'previous': | |
if(this._wrap) { | |
// If wrapping is turned on, position the container to the duplicated list item, set the current index manually | |
if(this._currentIndex <= 0) { | |
var wrappingPosition = -this._container.width() - this._slideWidth; | |
this._container.css({'left':wrappingPosition + 'px'}); | |
this._currentIndex = this._numSlides - 1; | |
} | |
} else { | |
if(this._currentIndex <= 0) { return; } | |
} | |
this._currentIndex--; | |
break; | |
case 'next': | |
if(this._wrap) { | |
// If wrapping is turned on, position the container to the first list item after the last move, set the current index manually | |
if(this._currentIndex >= this._numSlides - 1) { | |
$(_container).css({'left':'0'}); | |
this._currentIndex = 0; | |
} | |
} else { | |
if(this._currentIndex >= this._numSlides - 1) { return; } | |
} | |
this._currentIndex++; | |
break; | |
default: | |
// If direction isn't 'previous' or 'next' then it is an integer index | |
this._currentIndex = direction; | |
this.enableArrow('previous'); | |
this.enableArrow('next'); | |
} | |
// Disable or enable arrows based on position | |
if(!this._wrap) { | |
if(this._currentIndex == 0) { this.disableArrow('previous'); } | |
if(this._currentIndex == this._numSlides - 1) { this.disableArrow('next'); } | |
} | |
// Calculate the next position of the _container | |
var currentPosition = this._container.css('left'); | |
if(typeof direction == 'string') { | |
var calculation = direction == 'previous' ? (parseFloat(currentPosition) + this._slidesWidth) + this._spacing : parseFloat(currentPosition) - this._slidesWidth - this._spacing; | |
this.enableArrow(direction == 'next' ? 'previous' : 'next'); | |
} else { | |
var calculation = -(direction * this._slideWidth) + this._spacing; | |
} | |
// Disable all arrows while the animation takes place | |
this.disableArrows(); | |
switch(this._animationStyle) | |
{ | |
case "dissolve": | |
// Fade out the container, adjust it's left position, then fade it in | |
$(this._container).fadeOut('fast', function() { | |
$(this).css({'left': calculation + 'px'}); | |
$(this).fadeIn('medium'); | |
}); | |
break; | |
default: | |
$(this._container).animate({ left: (calculation) + 'px' }, "medium", function() { that.enableArrows() }); | |
} | |
// If we're wrapping, let's send the currentIndex - 1 if we're on the last one | |
if(this._wrap && this._currentIndex >= this._numSlides - 1) { | |
this._moveEvent.frame = 0; | |
this._moveEvent.direction = direction; | |
this._object.trigger(this._moveEvent); | |
return; | |
} | |
this._moveEvent.caller = this._object; | |
this._moveEvent.frame = this._currentIndex; | |
this._moveEvent.direction = direction; | |
$(this._object).trigger(this._moveEvent); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment