/*
* Sudo Slider ver 2.0.11 - jQuery plugin
* Written by Erik Kristensen info@webbies.dk.
* Based on Easy Slider 1.7 by Alen Grakalic http://cssglobe.com/post/5780/easy-slider-17-numeric-navigation-jquery-slider
* Although the two scripts doesn't share much code anymore. But Sudo Slider is still based on it.
*
* Dual licensed under the MIT
* and GPL licenses.
*
* Built for jQuery library
* http://jquery.com
*
*/
(function($)
{
$.fn.sudoSlider = function(options)
{
// Saves space in the minified version.
// It might look complicated, but it isn't. It's easy to make using "replace all" and it saves about ˝kb in the minified version.
var truev = true;
var falsev = !truev;
// default configuration properties
var defaults = {
prevNext: truev,
prevHtml: ' ',
nextHtml: ' ',
controlsShow: truev,
controlsAttr: 'id="controls"',
controlsFadeSpeed: '400',
controlsFade: truev,
insertAfter: truev,
firstShow: falsev,
firstHtml: ' first ',
lastShow: falsev,
lastHtml: ' last ',
numericAttr: 'class="controls"',
numericText: ['1'],
vertical: falsev,
speed: '800',
ease: 'swing',
auto: falsev,
pause: '2000',
continuous: falsev,
clickableAni: falsev,
numeric: falsev,
updateBefore: falsev,
history: falsev,
speedhistory: '400',
autoheight: truev,
customLink: falsev,
fade: falsev,
crossFade: truev,
fadespeed: '1000',
ajax: falsev,
loadingText: 'Loading Content...',
preloadAjax: falsev,
startSlide: falsev,
ajaxLoadFunction: falsev,
beforeAniFunc: falsev,
afterAniFunc: falsev,
uncurrentFunc: falsev,
currentFunc: falsev,
autowidth: truev,
slideCount: 1,
resumePause: falsev
};
var options = $.extend(defaults, options);
// To make it smaller.
// There is a way to make it even smaller, but that doesn't work with the public functions setOption() and getOption().
var option = [
options.controlsShow, /* option[0]/*controlsShow*/
options.controlsFadeSpeed,/* option[1]/*controlsFadeSpeed*/
options.controlsFade,/* option[2]/*controlsFade*/
options.insertAfter,/* option[3]/*insertAfter*/
options.firstShow,/* option[4]/*firstShow*/
options.lastShow,/* option[5]/*lastShow*/
options.vertical,/* option[6]/*vertical*/
options.speed,/* option[7]/*speed*/
options.ease,/* option[8]/*ease*/
options.auto,/* option[9]/*auto*/
options.pause,/* option[10]/*pause*/
options.continuous,/* option[11]/*continuous*/
options.prevNext,/* option[12]/*prevNext*/
options.numeric,/* option[13]/*numeric*/
options.numericAttr,/* option[14]/*numericAttr*/
options.numericText,/* option[15]/*numericText*/
options.clickableAni,/* option[16]/*clickableAni*/
options.history,/* option[17]/*history*/
options.speedhistory,/* option[18]/*speedhistory*/
options.autoheight,/* option[19]/*autoheight*/
options.customLink,/* option[20]/*customLink*/
options.fade,/* option[21]/*fade*/
options.crossFade,/* option[22]/*crossFade*/
options.fadespeed,/* option[23]/*fadespeed*/
options.updateBefore,/* option[24]/*updateBefore*/
options.ajax,/* option[25]/*ajax*/
options.preloadAjax,/* option[26]/*preloadAjax*/
options.startSlide,/* option[27]/*startSlide*/
options.ajaxLoadFunction,/* option[28]/*ajaxLoadFunction*/
options.beforeAniFunc,/* option[29]/*beforeAniFunc*/
options.afterAniFunc,/* option[30]/*afterAniFunc*/
options.uncurrentFunc,/* option[31]/*uncurrentFunc*/
options.currentFunc,/* option[32]/*currentFunc*/
options.prevHtml,/* option[33]/*prevHtml*/
options.nextHtml,/* option[34]/*nextHtml*/
options.loadingText,/* option[35]/*loadingText*/
options.firstHtml,/* option[36]/*firstHtml*/
options.controlsAttr,/* option[37]/*controlsAttr*/
options.lastHtml,/* option[38]/*lastHtml*/
options.autowidth,/* option[39]/*autowidth*/
options.slideCount,/* option[40]/*slideCount*/
options.resumePause/* option[41]/*resumePause*/
];
// Defining the base element.
// This is needed if i want to have public functions (And i want public functions).
var baseSlider = this;
return this.each(function()
{
/*
* Lets start this baby.
*/
// First we declare a lot of variables.
// Some of the names may be long, but they get minified.
var init,
ul,
li,
liConti,
s,
w,
h,
t,
ot,
nt,
ts,
clickable,
buttonclicked,
fading,
ajaxloading,
autoheightdocument,
numericControls,
numericContainer,
destroyed,
fontsmoothing,
controls,
html,
firstbutton,
lastbutton,
nextbutton,
prevbutton,
timeout,
destroyT,
oldSpeed,
dontCountinue,
dontCountinueInit,
obj = $(this);
initSudoSlider(obj, falsev, falsev);
function initSudoSlider(obj, destroyT, ajaxcallback)
{
//if (option[6]/*vertical*/) option[19]/*autoheight*/ = falsev; // With the new system of determining the position of the slides, this line is no longer needed.
destroyed = falsev; // In case this isn't the first init.
// There are some things we don't do at init.
init = truev; // I know it's an ugly workaround, but it works.
// If auto is on, so is continuous. (People tend to forget things they don't think about :p)
if (option[9]/*auto*/) option[11]/*continuous*/ = truev;
// Fix for nested list items
ul = obj.children("ul");
li = ul.children("li");
liConti = li;
// Some variables i'm gonna use alot.
s = li.length;
// The below two lines shouldn't be necessary anymore.
//w = li.eq(0).outerWidth(truev); // All slides must be same width, so this shouldn't be a problem. And it makes it posibble to mave multiple slides pr. "page" (2 slides in the viewport).
//h = li.eq(0).outerHeight(truev); // Same, just the height.
// Now we are going to fix the document, if it's 'broken'. (No
or no - ).
// I assume that it's can only be broken, if ajax is enabled. If it's broken without Ajax being enabled, the script doesn't have anything to fill the holes.
if (option[25]/*ajax*/)
{
// Is the ul element there?
if (ul.length == 0)
{
// No it's not, lets create it.
obj.append('');
ul = obj.children("ul");
}
// Do we have enough list elements to fill out all the ajax documents.
if (option[25]/*ajax*/.length > s)
{
// No we dont.
for (var i = 1; i <= option[25]/*ajax*/.length - s; i++) ul.append('
' + option[35] + '
');
li = ul.children("li");
s = li.length;
}
}
// Continuing with the variables.
t = 0;
ot = t;
nt = t;
ts = s-1;
clickable = truev;
buttonclicked = falsev;
fading = falsev;
ajaxloading = falsev;
autoheightdocument = 0;
numericControls = new Array();
numericContainer = falsev;
destroyed = falsev;
fontsmoothing = screen.fontSmoothingEnabled;
// Set obj overflow to hidden (and position to relative , if fade is enabled. )
obj.css("overflow","hidden");
if (obj.css("position") == "static") obj.css("position","relative"); // Fixed a lot of IE6 + IE7 bugs.
// Float items to the left, and make sure that all elements are shown.
li.css({'float': 'left', 'display': 'block'});
// Okay, now we have a lot of the variables in place, now we can check for some special conditions.
// If continuous is on, ajax is on and slideCount != 1. Then we have a problem.
// I the most efficiant way to fix it, is to preload everything before continuing.
if (ajaxcallback || ajaxcallback === 0){
/* Do a check if it can continue. */
if (dontCountinueInit) dontCountinueInit--;
if (!dontCountinueInit) option[25]/*ajax*/ = falsev; // If i don't do this, the making of the continuous clones below fuck up.
}
else if (option[25]/*ajax*/ && option[11]/*continuous*/ && option[40]/*slideCount*/ != 1)
{
// If those 3 things are truev, i basicly remove the ajax part, then continue the script.
// To do that, i have to preload everyone of them.
// This part is basicly a copy-paste of the preloading in the animate() function.
dontCountinueInit = 0;
for (var a = 0; a < s; a++)
{
if (option[25]/*ajax*/[a])
{
ajaxLoad(a, a, falsev, 0, function(){
initSudoSlider(obj, destroyT, a);
});
option[25]/*ajax*/[a] = falsev;
dontCountinueInit++;
}
}
}
if (!dontCountinueInit)
{
// The user doens't always put a text in the numericText.
// With this, if the user dont, the code will.
for(var i=0;i= 1 ;i--)
{
// First we create the elements, pretending AJAX is a city in Russia.
// ul.prepend(li.filter(":last-child").clone().css("margin-top","-"+ h +"px"));
var tmpchild = li.eq(-option[40]/*slideCount*/+i-1).clone();
a = a + tmpchild.outerWidth(truev);
tmpchild.css("margin-top","-"+ a +"px")
ul.prepend(tmpchild);
ul.append(li.eq(option[40]/*slideCount*/-i).clone().css({'z-index' : '0'}));
}
}
// IE6 bugs if i just use else here (atleast the IE6 in IETester (http://www.my-debugbar.com/wiki/IETester/HomePage)). No idea why, but it's IE6 and i'm not supprised.
if (!option[6]/*vertical*/)
{
for (i = option[40]/*slideCount*/;i >= 1 ;i--)
{
// First we create the elements, pretending AJAX is a city in Russia.
var tmpchild = li.eq(-option[40]/*slideCount*/+i-1).clone();
a = a + tmpchild.outerWidth(truev);
tmpchild.css("margin-left","-"+ a +"px")
ul.prepend(tmpchild);
ul.append(li.eq(option[40]/*slideCount*/-i).clone().css({'z-index' : '0'}));
}
}
// Now, lets check if AJAX really is a city in Russia.
if (option[25]/*ajax*/)
{
// Now we move from Russia back to reallity (nothing bad about the Russians, it's just a saying in Denmark.)
// Starting with putting the first document after the last.
if (option[25]/*ajax*/[0]) ajaxLoad('last', 0, falsev, 0, falsev);
// And putting the last document before the first.
if (option[25]/*ajax*/[s-1])
{
ajaxLoad('first', (s-1), falsev, 0, falsev);
// And then preloading the last document (the same document, but into it's entended position). No need to preload the first slide, it gets loaded elsewhere.
ajaxLoad(ts, ts, falsev, 0, falsev);
option[25]/*ajax*/[s-1] = falsev;
}
}
}
// Now that the slide content is in place, some adjustments can be made.
heightWidthAdjust();
// And i can make this variable for later use.
// The variable contains every - element.
liConti = ul.children("li");
// Display the controls.
controls = falsev;
if(option[0]/*controlsShow*/)
{
// Instead of just generating HTML, i make it a little smarter.
controls = $('');
if (option[3]/*insertAfter*/) $(obj).after(controls);
else $(obj).before(controls);
if(option[13]/*numeric*/) {
numericContainer = controls.prepend('
').children();
var substract = option[11]/*continuous*/ ? 1 : option[40]/*slideCount*/;
for(var i=0;i'+ option[15]/*numericText*/[i] +'')
.appendTo(numericContainer)
.click(function(){
goToSlide($(this).attr('rel') - 1, truev);
return falsev;
});
};
}
if(option[4]/*firstShow*/) firstbutton = makecontrol(option[36]/*firstHtml*/, "first");
if(option[5]/*lastShow*/) lastbutton = makecontrol(option[38]/*lastHtml*/, "last");
if(option[12]/*prevNext*/){
nextbutton = makecontrol(option[34]/*nextHtml*/, "next");
prevbutton = makecontrol(option[33]/*prevHtml*/, "prev");
}
};
// Preload elements.
if (option[26]/*preloadAjax*/) preloadEverything();
// Lets make those fast/normal/fast into some numbers we can make calculations with.
option[1]/*controlsFadeSpeed*/ = textSpeedToNumber(option[1]/*controlsFadeSpeed*/);
option[7]/*speed*/ = textSpeedToNumber(option[7]/*speed*/);
option[10]/*pause*/ = textSpeedToNumber(option[10]/*pause*/);
option[18]/*speedhistory*/ = textSpeedToNumber(option[18]/*speedhistory*/);
option[23]/*fadespeed*/ = textSpeedToNumber(option[23]/*fadespeed*/);
// And make sure that slideCount is a number.
option[40]/*slideCount*/ = parseInt(option[40]/*slideCount*/,10)
// Starting auto.
if(option[9]/*auto*/) timeout = startAuto(option[10]/*pause*/);
// customLinks. Easy to make, great to use.
// And if you wan't it even more flexible, you can use the public methods (http://webbies.dk/SudoSlider/help/) like sudoSlider.goToSlide('next');
if (option[20]/*customLink*/)
{
// Using live, that way javascript ajax-loaded buttons and javascript generated content will work.
$(option[20]/*customLink*/).live('click', function() {
a = $(this).attr('rel');
if (a) {
// Check for special events
if (a == 'stop')
{
option[9]/*auto*/ = falsev;
clearTimeout(timeout)
}
else if (a == 'start')
{
if (!option[11]/*continuous*/) baseSlider.setOption('continuous', truev);
timeout = startAuto(option[10]/*pause*/);
option[9]/*auto*/ = truev;
}
else if (a == 'block') clickable = falsev; // Simple, beautifull.
else if (a == 'unblock') clickable = truev; // -||-
// The general case.
// That means, typeof(a) == numbers and first,last,next,prev
// I dont make any kind of input validation, meaning that it's quite easy to break the script with non-valid input.
else if (clickable) goToSlide((a == parseInt(a)) ? a - 1 : a, truev);
}
return falsev;
});
}
// Lets make those bookmarks and back/forward buttons work.
// And startslide etc.
// + If re-initiated, the slider will be at the same slide.
if (destroyT) animate(destroyT,falsev,falsev,falsev);
else if (option[17]/*history*/) {
// Going to the correct slide at load.
$.address.init(function(e) {
if (!destroyT) animate(filterUrlHash(e.value),falsev,falsev,falsev);
})
// Sliding/fading to the correct slide, on url change.
.change(function(e) {
var i = filterUrlHash(e.value);
if (i != t) goToSlide(i, falsev);
});
}
// The startSlide setting only require one line of code. And here it is:
else if (option[27]/*startSlide*/) animate(option[27]/*startSlide*/ - 1,falsev,falsev,falsev);
// doing it anyway. good way to fix bugs.
// And i only preload the next and previous slide after init (which this is). So i'm doing it.
// + if i didn't do this, a lot of things wouldn't happen on page load. By always animating, i ensure that everthing that's supposed to happen, do happen.
else animate(0,falsev,falsev,falsev);
}
}
/*
* The functions do the magic.
*/
function preloadEverything()
{
for (var i=0;i<=ts;i++) // Preload everything.
{
if (option[25]/*ajax*/[i])
{
// If somethings is to be loaded, lets load it.
ajaxLoad(i, i, falsev, 0, falsev);
// Making sure it aint loaded again.
option[25]/*ajax*/[i] = falsev;
}
}
}
function heightWidthAdjust()
{
a = 0;
if(option[6]/*vertical*/)
{
for (var i = -1;i<=s;i++) a = a + li.eq(i).outerHeight(truev);
ul.height(a*4);
}
else
{
for (var i = -1;i<=s;i++) a = a + li.eq(i).outerWidth(truev);
ul.width(a*4);
}
}
function startAuto(pause)
{
return setTimeout(function(){
goToSlide("next", falsev);
},pause);
}
function textSpeedToNumber(speed)
{
if (parseInt(speed)) var returnspeed = parseInt(speed);
else
{
var returnspeed = 400;
switch(speed)
{
case 'fast':
returnspeed = 200;
case 'normal':
returnspeed = 400;
case 'medium':
returnspeed = 400;
case 'slow':
returnspeed = 600;
}
}
return returnspeed;
};
// I go a long way to save lines of code.
function makecontrol(html, action)
{
return $(html).prependTo(controls).click(function(){
goToSlide(action, truev);
return falsev;
});
}
// Simple functionA litle complecated function after moving the auto-slideshow code and introducing some "smart" animations. great work.
function goToSlide(i, clicked)
{
if (!destroyed)
{
// Ahhh, recursive functions. I love me.
if (option[9]/*auto*/)
{
var delay = option[7]/*speed*/;
if (fading && option[22]/*crossFade*/) delay = parseInt((delay)*(3/5));
else if (fading) delay = 0;
// Stopping auto if clicked. And also continuing after X seconds of inactivity.
if(clicked){
clearTimeout(timeout);
if (option[41]/*resumePause*/) timeout = startAuto(delay + option[41]/*resumePause*/);
}
// Continuing if not clicked.
else timeout = startAuto(option[10]/*pause*/ + delay);
}
if (option[21]/*fade*/)
{
fadeto(i, clicked);
}
else
{
if (option[11]/*continuous*/)
{
// Just a little smart thing, that stops the slider from performing way to "large" animations.
// Not necessary when using fade, therefore i placed it here.
a = t;
// Finding the "real" slide we are at. (-2 == 4).
if (a<0) a = a + s;
if (a>ts) a = a - s;
// And if i try to navigate to the neighbour, then why do it by sliding across the entire slider.
if (i == a + 1) i = 'next';
if (i == a - 1) i = 'prev';
// And when navigating from the first to the last (and the other way around).
if (a == 0 && i == ts) i = 'prev';
if (a == ts && i == 0) i = 'next';
}
// And now the animation itself.
animate(i,clicked,truev,falsev);
}
}
};
function runOnImagesLoaded(e,_cb)
{
// This function is based on the onImagesLoaded plugin by soundphed, that was in a comment on this page "http://engineeredweb.com/blog/09/12/preloading-images-jquery-and-javascript#comment-92".
e.each(function() {
var $imgs = (this.tagName.toLowerCase()==='img')?$(this):$('img',this),
_cont = this,
i = 0,
_done=function() {
if( typeof _cb === 'function' ) _cb(_cont);
};
if( $imgs.length ) {
$imgs.each(function() {
var _img = this,
_checki=function(e) {
if((_img.complete) || (_img.readyState=='complete'&&e.type=='readystatechange') )
{
if( ++i===$imgs.length ) _done();
}
else if( _img.readyState === undefined ) // dont for IE
{
$(_img).attr('src',$(_img).attr('src')); // re-fire load event
}
}; // _checki \\
$(_img).bind('load readystatechange', function(e){_checki(e);});
_checki({type:'readystatechange'}); // bind to 'load' event...
});
} else _done();
});
};
// Is the file a image? (This function is not only used in the Ajaxload function)
function imageCheck(file)
{
var len = file.length;
var ext = file.substr(len-4, 4);
if (ext == '.jpg' || ext == '.png' || ext == '.bmp' || ext == '.gif' || file.substr(len-5, 5) == '.jpeg') return truev;
return falsev;
}
function fadeControl (fadeOpacity,fadetime,nextcontrol)
{
if (!option[11]/*continuous*/)
{
if (nextcontrol)
{
var eA = nextbutton,
eB = lastbutton,
directionA = 'next',
directionB = 'last',
firstlastshow = option[5]/*lastShow*/;
}
else
{
var eA = prevbutton,
eB = firstbutton,
directionA = 'prev',
directionB = 'first',
firstlastshow = option[4]/*firstShow*/;
}
if (option[12]/*prevNext*/)
{
if (fadeOpacity == 0) eA.fadeOut(fadetime);
else eA.fadeIn(fadetime);
}
if (firstlastshow)
{
if (fadeOpacity == 0) eB.fadeOut(fadetime);
else eB.fadeIn(fadetime);
}
if(option[20]/*customLink*/)
{
$(option[20]/*customLink*/)
.filter(function(index) {
return ($(this).attr("rel") == directionA || $(this).attr("rel") == directionB);
})
.fadeTo(fadetime, fadeOpacity, function() { if (fadeOpacity == 0) $(this).hide();});
}
}
};
// Fade the controls, if we are at the end of the slide.
// It's all the different kind of controls.
function fadeControls (a,fadetime)
{
if(a==0) fadeControl (0,fadetime,falsev);
else fadeControl (1,fadetime,falsev);
// The new way of doing it.
if (a >= s - option[40]/*slideCount*/) fadeControl(0, fadetime, truev);
// Not using a else, because IE6 doesn't like that.
if (a < s - option[40]/*slideCount*/)fadeControl(1, fadetime, truev);
// Here is the old way of doing it.
/* if(a==ts) fadeControl (0,fadetime,truev);
else fadeControl (1,fadetime,truev);*/
};
// Updating the 'current' class
function setCurrent(i)
{
i = parseInt((i>ts) ? i=0 : ((i<0)? i= ts+i+1 : i)) + 1;
for(var a=0;ats) t=0;
if(t<1-option[40]/*slideCount*/) t=s-option[40]/*slideCount*/;
}
else
{
if(t>ts) t=0;
if(t<0) t=ts;
}
// Keeping the below line in case something else fucks up. (It shouldn't)
if (t==ts && !option[21]/*fade*/) preloadEverything();
if(!option[24]/*updateBefore*/) setCurrent(t);
adjustPosition();
clickable = truev;
if(option[17]/*history*/ && buttonclicked) window.location.hash = option[15]/*numericText*/[t];
if (!fading)
{
a = t + 1;
if (a<1) a = a + s;
if (a>s) a = a - s;
// Lets run the after animation function.
afterAniCall(li.eq(t), a)
if (option[11]/*continuous*/ && !option[21]/*fade*/) // Never needed if it's a fade animation.
{
// Might look complicated, and it is.
// To see the logic, you need to 'uncompress' the code.
// But it's basicly just determining which continuous-"clone" i need to call afterAniFunc on.
if (t < option[40]/*slideCount*/) afterAniCall(liConti.eq((t<0) ? t + option[40]/*slideCount*/ : t - option[40]/*slideCount*/), a);
if (t > ts - option[40]/*slideCount*/) afterAniCall(liConti.eq(option[40]/*slideCount*/ + t - ts - 1), a);
}
}
};
function afterAniCall(el, a)
{
if ($.isFunction(option[30]/*afterAniFunc*/)) option[30]/*afterAniFunc*/.call(el, a);
};
function beforeAniCall(el, a)
{
if ($.isFunction(option[29]/*beforeAniFunc*/)) option[29]/*beforeAniFunc*/.call(el, a);
};
// Convert the direction into a usefull number.
function filterDir(dir, ot)
{
var nt = t; // i dont want to mess with the 't' variable. This function doens't allways return the t-value, it can be used for other things.
switch(dir)
{
case "next":
nt = (ot>=ts) ? (option[11]/*continuous*/ ? nt+1 : ts) : nt+1;
break;
case "prev":
nt = (nt<=0) ? (option[11]/*continuous*/ ? nt-1 : 0) : nt-1;
break;
case "first":
nt = 0;
break;
case "last":
nt = ts;
break;
default:
nt = parseInt(dir);
break;
};
return nt;
};
// Load a ajax document (or i image) into a list element.
// If testing this locally (loading everything from a harddisk instead of the internet), it may not work.
// But then try to upload it to a server, and see it shine.
function ajaxLoad(i, l, adjust, speed, ajaxCallBack)
{
// Not as complicated as it looks.
var targetslide = (parseInt(i) || i == 0) ? li.eq(i) : (i == 'last') ? $('li:last', obj) : $('li:first', obj);
// What speed should the autoheight function animate with?
var ajaxspeed = (fading) ? (!option[22]/*crossFade*/ ? parseInt(option[23]/*fadespeed*/ * (2/5)) : option[23]/*fadespeed*/) : speed;
// The script itself is not using the 'tt' variable. But a custom function can use it.
var tt = l + 1;
if (imageCheck(option[25]/*ajax*/[l]))
{
// Load the image.
targetslide.html(' ').append($(new Image()).attr('src', option[25]/*ajax*/[l]));
// When the document is ready again, we launch autoadjust.
runOnImagesLoaded(targetslide,function(img){
var target = $(img).children();
// If the image is to wide, shrink it.
var a = 0;
finishImageLoading(target, a);
function finishImageLoading(target, a)
{
a++;
var width = target.width(),
height = target.height(),
slidewidth = target.parent().width();
// If width == 0, that means it's not ready yet.
// So we wait 5 1 ms.
if (width == 0 && a != 20) setTimeout(function() { finishImageLoading(target, a); }, 1);
else
{
target.attr({'oldheight' : height, 'oldwidth' : width});
// The last part (height:auto) forces the browser to think about the - elements height.
if (width > slidewidth) target.animate({ width: slidewidth, height: (height/width)*slidewidth}, 0).parent().animate({height: (height/width)*slidewidth}, 0).css('height', 'auto');
// If we want, we can launch a function here.
if ($.isFunction(option[28]/*ajaxLoadFunction*/)){option[28]/*ajaxLoadFunction*/.call($(img), tt, truev);}
// Lets just make some adjustments
ajaxAdjust(target.parent(), ajaxCallBack);
if (adjust) autoadjust(i, ajaxspeed);
}
}
});
}
else
{
// Load the document into the list element.
targetslide.load(option[25]/*ajax*/[l], function(response, status, xhr) {
// Lets just make some adjustments
ajaxAdjust($(this), ajaxCallBack);
if (adjust) adjustPosition();
if (status == "error" || !$(this).html()) $(this).html("Sorry but there was an error: " + (xhr.status ? xhr.status : 'no content') + " " + xhr.statusText);
// If we want, we can launch a function here.
if (status != "error" && $.isFunction(option[28]/*ajaxLoadFunction*/)){option[28]/*ajaxLoadFunction*/.call($(this), tt, falsev);}
// Lets adjust the height, i don't care if there's an error or not.
// var nheight = $(this).height(); // Why did i put that there??? Delete this comment when reason is found.
if (adjust) autoadjust(l, ajaxspeed);
});
}
};
function ajaxAdjust(target, ajaxCallBack){
if ($.isFunction(ajaxCallBack)) ajaxCallBack();
// If this is the "continuous" elements (the ones before the first and after the last).
heightWidthAdjust();
};
// It's not only a slider, it can also fade from slide to slide.
function fadeto(i, clicked)
{
if (i != t && !destroyed && clickable) // We doesn't want something to happen all the time. The URL can change a lot, and cause som "flickering".
{
ajaxloading = falsev;
// Update the current class of the buttons.
if (option[24]/*updateBefore*/) setCurrent(filterDir(i, ot));
// Only clickable if not clicked.
clickable = !clicked;
// Setting the speed.
var speed = (!clicked && !option[9]/*auto*/ && option[17]/*history*/) ? option[23]/*fadespeed*/ * (option[18]/*speedhistory*/ / option[7]/*speed*/) : option[23]/*fadespeed*/;
var ll = filterDir(i, ot);
// I don't want to fade to a continuous clone, i go directly to the target.
if(ll>ts) ll=0;
if(ll<0) ll=ts;
// Lets make sure the prev/next buttons also fade.
if(option[2]/*controlsFade*/) fadeControls (ll,option[1]/*controlsFadeSpeed*/);
// Lets load it before we animate to it.
if (option[25]/*ajax*/ && option[25]/*ajax*/[ll])
{
ajaxLoad(ll, ll, falsev, speed, function(){
option[25]/*ajax*/[ll] = falsev;
clickable = truev;
adjustPosition();
fadeto(ll, truev);
});
}
else
{
autoadjust(ll,option[23]/*fadespeed*/); // The height animation takes the full lenght of the fade animation (fadein + fadeout if it's not crossfading).
// Define the target.
var target = li.eq(ll);
// So lets run the function.
beforeAniCall(target, ll + 1)
// Crossfading?
if (option[22]/*crossFade*/)
{
// I clone the target, and fade it in, then hide the cloned element while adjusting the slider to show the real target.
target.clone().prependTo(obj).css({'z-index' : '100000', 'position' : 'absolute', 'list-style' : 'none', 'top' : '0', 'left' : '0'}).
// Lets fade it in.
hide().fadeIn(option[23]/*fadespeed*/, function() {
if (fontsmoothing) this.style.removeAttribute("filter"); // Fix cleartype
// So the animate function knows what to do.
clickable = truev;
fading = truev;
animate(ll,falsev,falsev,falsev); // Moving to the correct place.
// Removing the clone, if i dont, it will just be a pain in the ....
$(this).remove();
if(option[17]/*history*/ && clicked) window.location.hash = option[15]/*numericText*/[t]; // It's just one line of code, no need to make a function of it.
// Lets put that variable back to the default (and not during animation) value.
fading = falsev;
// Now run that after animation function.
// We already got the target and the slider number from earlier.
// So lets run the function.
afterAniCall(target, ll + 1);
});
}
else
{
// fadeOut and fadeIn.
var fadeinspeed = parseInt((speed)*(3/5)),
fadeoutspeed = speed - fadeinspeed,
// I set the opacity to something higher than 0, because if it's 0, the content that i try to read (to make the autoheight work etc.) aint there.
noncrossfadetargets = li.children();
noncrossfadetargets.stop().fadeTo(fadeoutspeed, 0.0001, function(){
// So the animation function knows what to do.
clickable = truev;
fading = truev;
animate(ll,falsev,falsev,falsev); // Moving to the correct place.
// Only clickable if not clicked.
clickable = !clicked;
// Now, lets fade the slider back in.
// Got no idea why the .add(li) is nesecary, but it is. (If it isn't there, the first slide never fades back in).
noncrossfadetargets.add(li).stop().fadeTo(fadeinspeed, 1, function(){
if (fontsmoothing) this.style.removeAttribute("filter"); // Fix cleartype
if(option[17]/*history*/ && clicked) window.location.hash = option[15]/*numericText*/[t]; // It's just one line of code, no need to make a function of it.
clickable = truev;
fading = falsev;
// Now run that after animation function.
// We already got the target and the slider number from earlier.
// So lets run the function.
afterAniCall(target, ll + 1);
});
});
}
}
}
};
function animate(dir,clicked,time,ajaxcallback) // (Direction, did the user click something, is this to be done in >1ms?, is this inside a ajaxCallBack?)
{
if ((clickable && !destroyed && (filterDir(dir, ot) != t || init)) || ajaxcallback)
{
ajaxloading = falsev;
clickable = (!clicked && !option[9]/*auto*/) ? truev : option[16]/*clickableAni*/;
// to the adjust function.
buttonclicked = clicked;
ot = t;
t = filterDir(dir, ot);
if (option[24]/*updateBefore*/) setCurrent(t);
// Calculating the speed to do the animation with.
var diff = Math.sqrt(Math.abs(ot-t)),
speed = parseInt(diff*option[7]/*speed*/);
if (!clicked && !option[9]/*auto*/) speed = parseInt(diff*option[18]/*speedhistory*/); // Auto:truev and history:truev doens't work well together, and they ain't supposed to.
if (!time) speed = 0;
// Ajax begins here
// I also these variables in the below code (running custom function).
var i = t;
if (i<0) i = i + s;
if (i>ts) i = i - s;
if (ajaxcallback)
{
speed = oldSpeed;
// Do a check if it can continue.
if (dontCountinue) dontCountinue--;
}
else if (option[25]/*ajax*/)
{
// Loading the target slide, if not already loaded.
if (option[25]/*ajax*/[i])
{
ajaxLoad(i, i, truev, speed, falsev);
option[25]/*ajax*/[i] = falsev;
ajaxloading = truev;
}
// The slider need to have all slides that are scrolled over loaded, before it can do the animation.
// That's not easy, because the slider is only loaded once a callback is fired.
if (!fading)
{
var aa = (ot>t) ? t : ot,
ab = (ot>t) ? ot : t;
dontCountinue = 0;
oldSpeed = speed;
for (var a = aa; a <= ab; a++)
{
if (a<=ts && a>=0 && option[25]/*ajax*/[a])
{
ajaxLoad(a, a, falsev, speed, function(){
animate(dir,clicked,time, a);
});
option[25]/*ajax*/[a] = falsev;
dontCountinue++;
}
}
}
// Then we have to preload the next one.
if (i + 1 <= ts && option[25]/*ajax*/[i + 1])
{
ajaxLoad(i + 1, i + 1, falsev, 0, falsev);
option[25]/*ajax*/[i + 1] = falsev;
}
}
if (!dontCountinue)
{
// Lets create a variable for later use
// Here, IE6 bugs if i write " if (t < 0) ". (At least it did at some point, don't now if it's still the case).
if (t < 1-1) var contiElement = liConti.eq(option[40]/*slideCount*/+t);
if (t > ts) var contiElement = liConti.eq(t-s-option[40]/*slideCount*/);
// Ajax ends here
if (!fading)
{
// Lets run the before animation function.
beforeAniCall(li.eq(i), i+1)
if (option[11]/*continuous*/)
{
if (t < option[40]/*slideCount*/) beforeAniCall(liConti.eq((t<0) ? t + option[40]/*slideCount*/ : t - option[40]/*slideCount*/),i+1);
if (t > ts - option[40]/*slideCount*/ || t == -option[40]/*slideCount*/) beforeAniCall(liConti.eq((t == -option[40]/*slideCount*/) ? -1 : option[40]/*slideCount*/ + t - ts - 1),i+1);
}
}
// Start animation.
if (!fading && !ajaxloading) autoadjust(t, speed);
if(option[6]/*vertical*/) {
var p = getSlidePos(t, falsev);
ul.animate(
{ marginTop: p },
{
queue:falsev,
duration:speed,
easing:option[8]/*ease*/,
complete:adjust
}
);
}
else
{
var p = getSlidePos(t, truev);
ul.animate(
{ marginLeft: p},
{
queue:falsev,
duration:speed,
easing:option[8]/*ease*/,
complete:adjust
}
);
};
// End animation.
// Fading the next/prev/last/first controls in/out if needed.
if(option[2]/*controlsFade*/)
{
var fadetime = option[1]/*controlsFadeSpeed*/;
if (!clicked && !option[9]/*auto*/) fadetime = (option[18]/*speedhistory*/ / option[7]/*speed*/) * option[1]/*controlsFadeSpeed*/;
if (!time) fadetime = 0;
if (fading) fadetime = parseInt((option[23]/*fadespeed*/)*(3/5));
fadeControls (t,fadetime);
}
// Stop init, first animation is done.
init = falsev; //nasty workaround, but it works.
};
}
};
function returnOptionNumber(name) // Get the number from the name.
{
var optionsUserName = [
'controlsShow',
'controlsFadeSpeed',
'controlsFade',
'insertAfter',
'firstShow',
'lastShow',
'vertical',
'speed',
'ease',
'auto',
'pause',
'continuous',
'prevNext',
'numeric',
'numericAttr',
'numericText',
'clickableAni',
'history',
'speedhistory',
'autoheight',
'customLink',
'fade',
'crossFade',
'fadespeed',
'updateBefore',
'ajax',
'preloadAjax',
'startSlide',
'ajaxLoadFunction',
'beforeAniFunc',
'afterAniFunc',
'uncurrentFunc',
'currentFunc',
'prevHtml',
'nextHtml',
'loadingText',
'firstHtml',
'controlsAttr',
'lastHtml',
'autowidth',
'slideCount',
'resumePause'
];
for(var i=0;i s) pos = s; // If you try to add a slide after the last slide fix.
var html = '
- ' + html + '
';
if (!pos || pos == 0) ul.prepend(html);
else li.eq(pos -1).after(html);
// Finally, we make it work again.
if (pos < destroyT || (!pos || pos == 0)) destroyT++;
if (option[15]/*numericText*/.length < pos){ option[15]/*numericText*/.length = pos;}
option[15]/*numericText*/.splice(pos,0,numtext || parseInt(pos,10)+1);
baseSlider.init();
}
baseSlider.removeSlide = function(pos){
pos--; // 1 == the first.
// First we make it easier to work.
baseSlider.destroy();
// Then we work.
li.eq(pos).remove();
option[15]/*numericText*/.splice(pos,1);
if (pos < destroyT) destroyT--;
// Finally, we make it work again.
baseSlider.init();
}
baseSlider.goToSlide = function(a){
goToSlide((a == parseInt(a)) ? a - 1 : a, truev);
}
baseSlider.block = function(){
clickable = falsev; // Simple, beautifull.
}
baseSlider.unblock = function(){
clickable = truev; // Simple, beautifull.
}
baseSlider.startAuto = function(){
if (!option[11]/*continuous*/) baseSlider.setOption('continuous', truev);
option[9]/*auto*/ = truev;
timeout = startAuto(option[10]/*pause*/);
}
baseSlider.stopAuto = function(){
option[9]/*auto*/ = falsev;
clearTimeout(timeout);
}
baseSlider.destroy = function(){
destroyT = t;
// First, i remove the controls.
if (controls) controls.remove(); // that's it.
// Now to set a variable, so nothing is run.
destroyed = truev; // No animation, no fading, no clicking from now.
// Then remove the customLink bindings:
$(option[20]/*customLink*/).die("click");
// Now remove the "continuous clones".
if (option[11]/*continuous*/)
{
for (a=1;a<=option[40]/*slideCount*/;a++)
{
liConti.eq(a-1).remove();
liConti.eq(-a).remove();
}
}
// And now it's done. The only way to make this slider do something visible, is by making a new init.
}
baseSlider.init = function(){
if (destroyed) {
initSudoSlider(obj, destroyT, falsev);
}
}
baseSlider.adjust = function(speed){
if (!speed) speed = 0;
heightWidthAdjust();
autoadjust(i, speed)
}
baseSlider.getValue = function(a){
switch(a)
{
case 'currentSlide':
return t + 1;
case 'totalSlides':
return s;
case 'clickable':
return clickable;
case 'destroyed':
return destroyed;
}
return undefined;
}
});
};
})(jQuery);