/*
FILE ARCHIVED ON 12:36:45 Jan 12, 2009 AND RETRIEVED FROM THE
AN OPENWAYBACK INSTANCE ON 21:53:53 Jun 4, 2024.
JAVASCRIPT APPENDED BY OPENWAYBACK, COPYRIGHT INTERNET ARCHIVE.
ALL OTHER CONTENT MAY ALSO BE PROTECTED BY COPYRIGHT (17 U.S.C.
SECTION 108(a)(3)).
*/
/**
* jCarousel - Riding carousels with jQuery
* https://webarchive.library.unt.edu/eot2008/20090112123645/http://sorgalla.com/jcarousel/
*
* Copyright (c) 2006 Jan Sorgalla (https://webarchive.library.unt.edu/eot2008/20090112123645/http://sorgalla.com)
* Dual licensed under the MIT (MIT-LICENSE.txt)
* and GPL (GPL-LICENSE.txt) licenses.
*
* Built on top of the jQuery library
* https://webarchive.library.unt.edu/eot2008/20090112123645/http://jquery.com
*
* Inspired by the "Carousel Component" by Bill Scott
* https://webarchive.library.unt.edu/eot2008/20090112123645/http://billwscott.com/carousel/
*/
jQuery.fn.extend({
/**
* Creates a carousel for all matched elements.
*
* @example $("#mycarousel").jcarousel();
* @before
First item
Second item
* @result
*
*
*
*
*
*
First item
*
Second item
*
*
*
*
* @name jcarousel
* @type jQuery
* @param Hash o A set of key/value pairs to set as configuration properties.
* @cat jCarousel
*/
jcarousel: function(o) {
return this.each(function() {
new jQuery.jcarousel(this, o);
});
}
});
jQuery.extend({
/**
* The jCarousel object.
*
* @constructor
* @private
* @name jQuery.jcarousel
* @param Object e The element to create the carousel for.
* @param Hash o A set of key/value pairs to set as configuration properties.
* @cat jCarousel
*/
jcarousel: function(e, o) {
// Public api of the jCarousel object passed to the
// handler callback functions.
var publ = this;
/**
* Returns the scope of the carousel which is the outer
*
element containing the required markup (
list,
* prev/next buttons etc.).
*
* @name scope
* @type Element
* @cat jCarousel
*/
publ.scope = function() { return priv.scope; };
/**
* Returns the list.
*
* @name list
* @type Element
* @cat jCarousel
*/
publ.list = function() { return priv.list; };
/**
* Returns the number of elements of the list.
*
* @name size
* @type Number
* @cat jCarousel
*/
publ.size = function() { return priv.size; };
/**
* (Re)initialises the carousel.
*
* @name init
* @type undefined
* @param Hash o A set of key/value pairs to set as configuration properties.
* @cat jCarousel
*/
publ.init = function(o) { return priv.init(o); };
/**
* Returns a jQuery object with list element for the given index.
*
* @name get
* @type jQuery
* @param Number idx The index of the element.
* @cat jCarousel
*/
publ.get = function(idx) { return priv.get(idx); };
/**
* Adds an element for the given index to the list.
* If the element already exists, it updates the inner html.
* Returns the created element as jQuery object.
*
* @name add
* @type jQuery
* @param Number idx The index of the element.
* @param String html The innerHTML of the element.
* @cat jCarousel
*/
publ.add = function(idx, html) { return priv.add(idx, html); };
/**
* Returns true if all elements in the given range already exist,
* false otherwise.
*
* @name available
* @type Boolean
* @param Number first The first index of the element range.
* @param Number last The last index of the element range.
* @cat jCarousel
*/
publ.available = function(first, last) { return last == undefined ? priv.end >= first : priv.end >= last; };
/**
* Notifies the carousel object that updating of the carousel elements
* has been finished. Must be called from the loadItemHandler callback
* function after adding items with publ.add().
*
* @name loaded
* @type undefined
* @cat jCarousel
*/
publ.loaded = function() { priv.loaded(); };
/**
* Moves the carousel forwards.
*
* @name next
* @type undefined
* @cat jCarousel
*/
publ.next = function() { priv.next(); };
/**
* Moves the carousel backwards.
*
* @name prev
* @type undefined
* @cat jCarousel
*/
publ.prev = function() { priv.prev(); };
/**
* Moves the carousel to a certain position.
*
* @name next
* @type undefined
* @param Number i The index of the element to scoll to.
* @cat jCarousel
*/
publ.scroll = function(i) { if (publ.available(i)) { priv.scroll(i); } };
// Private methods/variables
var priv = {
o: {
orientation: "horizontal",
itemStart: 1,
itemVisible: 4,
itemScroll: 1,
scrollAnimation: "fast",
autoScroll: 0,
autoScrollStopOnInteract: true,
autoScrollStopOnMouseover: false,
autoScrollResumeOnMouseout: false,
wrap: false,
wrapPrev: false,
itemWidth: null,
itemHeight: null,
loadItemHandler: null,
nextButtonStateHandler: null,
prevButtonStateHandler: null,
itemFirstInHandler: null,
itemFirstOutHandler: null,
itemLastInHandler: null,
itemLastOutHandler: null,
itemVisibleInHandler: null,
itemVisibleOutHandler: null,
noButtons: false,
buttonNextHTML: '',
buttonPrevHTML: ''
},
scope: null,
list: null,
horiz: true,
top: 0,
left: 0,
size: 0,
end: 0,
first: 0,
prevFirst: 0,
last: 0,
prevLast: 0,
inAnimation: false,
autoTimer: null,
nextClick: function() { priv.next(); },
prevClick: function() { priv.prev(); },
itemFormat: {
"float": "left",
"styleFloat": "left",
"overflow": "hidden",
"listStyle": "none"
},
options: function(o) {
if (o)
jQuery.extend(priv.o, o);
priv.o.itemStart = Math.max(1, priv.intval(priv.o.itemStart));
priv.o.itemScroll = priv.o.itemScroll || priv.o.itemVisible;
if (priv.o.itemWidth)
priv.itemFormat.width = priv.o.itemWidth + "px";
if (priv.o.itemHeight)
priv.itemFormat.height = priv.o.itemHeight + "px";
priv.horiz = priv.o.orientation == "vertical" ? false : true;
},
init: function(o) {
priv.options(o);
if (priv.size == 0) {
var dummy = priv.format(document.createElement("li"), 1).get(0);
priv.list.appendChild(dummy);
}
var i = jQuery("li", priv.list).get(0);
var itemWidth = i.offsetWidth + priv.margin(i, "marginLeft") + priv.margin(i, "marginRight");
var itemHeight = i.offsetHeight + priv.margin(i, "marginTop") + priv.margin(i, "marginBottom");
if (priv.horiz) {
priv.dimension = itemWidth;
var clipW = itemWidth * priv.o.itemVisible - priv.margin(i, "marginRight");
var clipH = itemHeight;
} else {
priv.dimension = itemHeight;
var clipW = itemWidth;
var clipH = itemHeight * priv.o.itemVisible - priv.margin(i, "marginBottom");
}
jQuery(".jcarousel-clip", priv.scope).css({
"zIndex": "2",
"padding": 0,
"margin": 0,
"width": clipW + "px",
"height": clipH + "px",
"overflow": "hidden",
"position": "relative"
});
if (dummy != undefined)
priv.list.removeChild(dummy);
priv.resize();
},
prepare: function(e, o) {
priv.options(o);
if (e.nodeName == "UL" || e.nodeName == "OL") {
priv.list = e;
var scope = jQuery(priv.list).parent().get(0);
if (jQuery.className.has(scope.className, "jcarousel-clip")) {
if (!jQuery.className.has(jQuery(scope).parent().get(0).className, "jcarousel-scope"))
scope = jQuery(scope).wrap('');
scope = jQuery(scope).parent().get(0);
} else if (!jQuery.className.has(scope.className, "jcarousel-scope"))
scope = jQuery(priv.list).wrap('').parent().get(0);
priv.scope = scope;
} else {
priv.scope = e;
priv.list = jQuery("ul", priv.scope).get(0) || jQuery("ol", priv.scope).get(0);
}
priv.size = priv.end = jQuery("li", priv.list).size();
if (priv.size > 0) {
var idx = 1;
jQuery("li", priv.list).each(function() { priv.format(this, idx++); });
}
if (!jQuery.className.has(jQuery(priv.list).parent().get(0).className, "jcarousel-clip"))
jQuery(priv.list).wrap('');
if (!priv.o.noButtons) {
if (jQuery(".jcarousel-prev", priv.scope).size() == 0) {
var dummy = jQuery(document.createElement("div")).html(priv.o.buttonPrevHTML).get(0);
jQuery(".jcarousel-clip", priv.scope).before(jQuery(dummy.firstChild).addClass("jcarousel-prev"));
}
if (jQuery(".jcarousel-next", priv.scope).size() == 0) {
var dummy = jQuery(document.createElement("div")).html(priv.o.buttonNextHTML).get(0);
jQuery(".jcarousel-clip", priv.scope).before(jQuery(dummy.firstChild).addClass("jcarousel-next"));
}
jQuery(".jcarousel-prev", priv.scope).css({"zIndex": "3"});
jQuery(".jcarousel-next", priv.scope).css({"zIndex": "3"});
}
if (priv.o.autoScrollStopOnMouseover) {
if (priv.o.autoScrollResumeOnMouseout) {
jQuery(".jcarousel-clip", priv.scope).bind("mouseover", function() { priv.stopAuto(); }).bind("mouseout", function() { priv.startAuto(); });
} else {
jQuery(".jcarousel-clip", priv.scope).bind("mouseover", function() { priv.disableAuto(); });
}
}
priv.top = 0; //priv.intval(jQuery(priv.list).css("top"));
priv.left = 0; //priv.intval(jQuery(priv.list).css("left"));
jQuery(priv.list).css({
"zIndex": "1",
"position": "relative",
"top": priv.top + "px",
"left": priv.left + "px",
"margin": 0,
"padding": 0
}).addClass("jcarousel-list");
jQuery(priv.scope).addClass("jcarousel-scope").show().find(":hidden").show();
},
get: function(idx) {
return jQuery(".jcarousel-item-" + idx, priv.list);
},
add: function(idx, s) {
var item = priv.get(idx);
if (item.size() == 0) {
var item = priv.format(document.createElement("li"), idx);
jQuery(priv.list).append(item);
priv.size++;
if (priv.size > priv.end)
priv.end = priv.size;
priv.resize();
}
return item.html(s);
},
available: function(first, last) {
if (priv.end >= last)
return true;
priv.end = last;
return false;
},
load: function(first, last) {
if (priv.o.loadItemHandler == null)
return priv.loaded();
priv.buttons(false, false);
priv.o.loadItemHandler(publ, first, last, priv.available(first, last));
},
loaded: function() {
if (priv.first > 1 && priv.last < priv.size) {
priv.buttons(true, true);
} else if (priv.first == 1 && priv.last < priv.size) {
priv.buttons(true, priv.o.wrapPrev);
} else if (priv.first > 1 && priv.last >= priv.size) {
priv.buttons(priv.o.wrap, true);
}
},
next: function() {
priv.stopAuto();
if (priv.o.autoScrollStopOnInteract)
priv.disableAuto();
priv.doNext();
},
doNext: function() {
priv.scroll((priv.o.wrap && priv.last == priv.size) ? 1 : priv.first + priv.o.itemScroll);
if (priv.o.wrap || priv.last < priv.size)
priv.startAuto();
},
prev: function() {
priv.stopAuto();
if (priv.o.autoScrollStopOnInteract)
priv.disableAuto();
priv.doPrev();
},
doPrev: function() {
priv.scroll((priv.o.wrapPrev && priv.first == 1) ? priv.size - priv.o.itemVisible + 1 : priv.first - priv.o.itemScroll);
priv.startAuto();
},
scroll: function(idx) {
if (priv.inAnimation)
return;
priv.inAnimation = false;
priv.prevFirst = priv.first;
priv.prevLast = priv.last;
idx = idx < 1 ? 1 : idx;
var last = idx + priv.o.itemVisible - 1;
last = (last > priv.size) ? priv.size : last;
var first = last - priv.o.itemVisible + 1;
first = (first < 1) ? 1 : first;
last = first + priv.o.itemVisible - 1;
priv.first = first;
priv.last = last;
priv.animate();
},
animate: function() {
var pos = priv.dimension * (priv.first - 1) * -1;
priv.notify(priv.prevFirst, priv.prevLast, priv.first, priv.last, "onBeforeAnimation");
if (priv.o.scrollAnimation) {
priv.inAnimation = true;
jQuery(priv.list).animate(priv.horiz ? {"left": pos} : {"top": pos}, priv.o.scrollAnimation, function() { priv.scrolled(); });
} else {
jQuery(priv.list).css(priv.horiz ? "left" : "top", pos + "px");
priv.scrolled();
}
},
scrolled: function() {
if (priv.first == 1)
jQuery(priv.list).css("top", priv.top + "px").css("left", priv.left + "px");
priv.inAnimation = false;
priv.notify(priv.prevFirst, priv.prevLast, priv.first, priv.last, "onAfterAnimation");
priv.load(priv.last + 1, priv.last + priv.o.itemScroll);
},
handler: function(handler, evt, state, i1, i2, i3, i4) {
if (priv.o[handler] == undefined || (typeof priv.o[handler] != 'object' && evt != "onAfterAnimation"))
return;
var handler = typeof priv.o[handler] == 'object' ? priv.o[handler][evt] : priv.o[handler];
if (typeof handler != 'function')
return;
if (i2 == undefined) {
priv.get(i1).each(function() { handler(publ, this, i1, state); });
return;
}
for (var i = i1; i <= i2; i++) {
if (!(i >= i3 && i <= i4))
priv.get(i).each(function() { handler(publ, this, i, state); });
}
},
notify: function(prevFirst, prevLast, first, last, evt) {
var state = prevFirst == 0 ? "init" : (prevFirst < first ? "next" : "prev");
if (prevFirst != first) {
priv.handler("itemFirstOutHandler", evt, state, prevFirst);
priv.handler("itemFirstInHandler", evt, state, first);
}
if (prevLast != last) {
priv.handler("itemLastOutHandler", evt, state, prevLast);
priv.handler("itemLastInHandler", evt, state, last);
}
priv.handler("itemVisibleInHandler", evt, state, first, last, prevFirst, prevLast);
priv.handler("itemVisibleOutHandler", evt, state, prevFirst, prevLast, first, last);
},
buttons: function(next, prev) {
if (priv.o.noButtons)
return;
jQuery(".jcarousel-next", priv.scope)[next ? "bind" : "unbind"]("click", priv.nextClick)[next ? "removeClass" : "addClass"]("jcarousel-next-disabled")[next ? "removeAttr" : "attr"]("disabled", true);
jQuery(".jcarousel-prev", priv.scope)[prev ? "bind" : "unbind"]("click", priv.prevClick)[prev ? "removeClass" : "addClass"]("jcarousel-prev-disabled")[prev ? "removeAttr" : "attr"]("disabled", true);
if (priv.o.nextButtonStateHandler != null)
jQuery(".jcarousel-next", priv.scope).each(function() { priv.o.nextButtonStateHandler(publ, this, next); });
if (priv.o.prevButtonStateHandler != null)
jQuery(".jcarousel-prev", priv.scope).each(function() { priv.o.prevButtonStateHandler(publ, this, prev); });
},
startAuto: function() {
if (priv.o.autoScroll > 0)
priv.autoTimer = setTimeout(function() { priv.doNext(); }, priv.o.autoScroll * 1000);
},
stopAuto: function() {
if (priv.autoTimer == null)
return;
clearTimeout(priv.autoTimer);
priv.autoTimer = null;
},
disableAuto: function() {
priv.stopAuto();
priv.o.autoScroll = 0;
},
resize: function() {
if (priv.size == 0)
return;
if (priv.horiz)
jQuery(priv.list).css("width", priv.size * priv.dimension + 100 + "px");
else
jQuery(priv.list).css("height", priv.size * priv.dimension + 100 + "px");
},
format: function(item, idx) {
return jQuery(item).css(priv.itemFormat).addClass("jcarousel-item-" + idx);
},
margin: function(e, p) {
if (p == "marginRight" && jQuery.browser.safari) {
var old = {"display": "block", "float": "none", "width": "auto"}, oWidth, oWidth2;
jQuery.swap(e, old, function() { oWidth = e.offsetWidth; });
old["marginRight"] = 0;
jQuery.swap(e, old, function() { oWidth2 = e.offsetWidth; });
return oWidth2 - oWidth;
}
return priv.intval(jQuery.css(e, p));
},
intval: function(v) {
v = parseInt(v);
return isNaN(v) ? 0 : v;
}
};
// Initialize the carousel
priv.prepare(e, o);
priv.init();
priv.buttons(false, false);
priv.load(1, priv.o.itemStart + priv.o.itemVisible);
priv.scroll(priv.o.itemStart);
priv.startAuto();
}
});