1/* 2 * Sudo Slider ver 1.0.12 - jQuery plugin 3 * Written by Erik Kristensen [email protected]. 4 * Based on Easy Slider 1.7 by Alen Grakalic http://cssglobe.com/post/5780/easy-slider-17-numeric-navigation-jquery-slider 5 * 6 * Dual licensed under the MIT 7 * and GPL licenses. 8 * 9 * Built for jQuery library 10 * http://jquery.com 11 * 12 */ 13 /* 14 TODO: 15 Finding and fixing bugs. (No known bugs atm.) 16 17 TODO for next major version: (i've had 10 minor versions now, don't think i'm ever going to do a major). 18 */ 19(function($) 20{ 21 $.fn.sudoSlider = function(options) 22 { 23 if (typeof(options) != 'object' && options != '' && options) 24 { 25 // Here, i just trigger it to do something, it's way down the actual action happens. 26 this.each(function(){ 27 $(this).trigger("sudoSliderEvent", [options]); 28 }); 29 } 30 else 31 { 32 // default configuration properties 33 var defaults = { 34 prevNext: true, 35 prevHtml: '<a href="#" class="prevBtn"> previous </a>', 36 nextHtml: '<a href="#" class="nextBtn"> next </a>', 37 controlsShow: true, 38 controlsAttr: 'id="controls"', 39 controlsFadeSpeed: '400', 40 controlsFade: true, 41 insertAfter: true, 42 firstShow: false, 43 firstHtml: '<a href="#" class="firstBtn"> first </a>', 44 lastShow: false, 45 lastHtml: '<a href="#" class="lastBtn"> last </a>', 46 numericAttr: 'class="controls"', 47 numericText: ['1'], 48 vertical: false, 49 speed: '800', 50 ease: 'swing', 51 auto: false, 52 pause: '2000', 53 continuous: false, 54 clickableAni: false, 55 numeric: false, 56 updateBefore: false, 57 history: false, 58 speedhistory: '400', 59 autoheight: true, 60 customLink: false, 61 fade: false, 62 crossFade: true, 63 fadespeed: '1000', 64 ajax: false, 65 loadingText: false, 66 preloadAjax: false, 67 startSlide: false, 68 imgAjaxFunction: false, 69 docAjaxFunction: false, 70 beforeAniFunc: false, 71 afterAniFunc: false, 72 uncurrentFunc: false, 73 currentFunc: false 74 }; 75 var options = $.extend(defaults, options); 76 77 // To make it smaller when minimized. 78 // Not including the variables only used once in the code. 79 // I just found out that this (as in now, not the same as final release) makes the script 572 bytes smaller. (That's about 6%) 80 //var optionscontrolsShow = options.controlsShow; // Only used once. 81 var optionscontrolsFadeSpeed = options.controlsFadeSpeed; 82 //var optionscontrolsBefore = options.controlsBefore; // Only used once. 83 //var optionscontrolsAfter = options.controlsAfter; // Only used once. 84 var optionscontrolsFade = options.controlsFade; 85 //var optionsinsertAfter = options.insertAfter;// Only used once. 86 var optionsfirstShow = options.firstShow; 87 var optionslastShow = options.lastShow; 88 var optionsvertical = options.vertical; 89 var optionsspeed = options.speed; 90 var optionsease = options.ease; 91 var optionsauto = options.auto; 92 var optionspause = options.pause; 93 var optionscontinuous = options.continuous; 94 var optionsprevNext = options.prevNext; 95 var optionsnumeric = options.numeric; 96 var optionsnumericAttr = options.numericAttr; 97 var optionsnumericText = options.numericText; 98 //var optionsclickableAni = options.clickableAni; // Only used once. 99 var optionshistory = options.history; 100 var optionsspeedhistory = options.speedhistory; 101 var optionsautoheight = options.autoheight; 102 var optionscustomLink = options.customLink; 103 var optionsfade = options.fade; 104 var optionscrossFade = options.crossFade; 105 var optionsfadespeed = options.fadespeed; 106 var optionsupdateBefore = options.updateBefore; 107 var optionsajax = options.ajax; 108 //var optionspreloadAjax= options.preloadAjax; // Only used once. 109 var optionsstartSlide = options.startSlide; 110 var optionsimgAjaxFunction = options.imgAjaxFunction; 111 var optionsdocAjaxFunction = options.docAjaxFunction; 112 var optionsbeforeAniFunc = options.beforeAniFunc; 113 var optionsafterAniFunc = options.afterAniFunc; 114 var optionsuncurrentFunc = options.uncurrentFunc; 115 var optionscurrentFunc = options.currentFunc; 116 117 return this.each(function() 118 { 119 // There are some things we don't do at init. 120 var init = true; // I know it's an ugly workaround, but it works. 121 // If auto is on, so is continuous. (People tend to forget things they don't think about :p) 122 if (optionsauto) optionscontinuous = true; 123 124 // Setting up some variables. 125 var obj = $(this); 126 127 // Fix for nested list items 128 var ul = obj.children("ul"); 129 var li = ul.children("li"); 130 131 // Some variables i'm gonna use alot. 132 var s = li.length; 133 var w = li.eq(0).width();
133 // All slides must be same width, so this shouldn't be a problem. 134 var h = obj.height(); 135 136 // Now we are going to fix the document, if it's 'broken'. (No <ul> or no <li>). 137 // 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. 138 if (optionsajax) 139 { 140 // Is the ul element there? 141 if (ul.length == 0) 142 { 143 // No it's not, lets create it. 144 obj.append('<ul></ul>'); 145 ul = obj.children("ul"); 146 } 147 148 // Do we have enough list elements to fill out all the ajax documents. 149 if (optionsajax.length > s) 150 { 151 // No we dont. 152 for (var i = 1; i <= optionsajax.length - s; i++) ul.append('<li><p>' + returnFunnyLoadingText() + '</p></li>'); 153 li = ul.children("li"); 154 s = li.length; 155 w = li.eq(0).width(); 156 } 157 } 158 // i just love stackoverflow (http://stackoverflow.com/questions/182112/what-are-some-funny-loading-statements-to-keep-users-amused-closed) 159 // i know this is just an easter egg, because you really should never see it. 160 // But what the heck, i want it. 161 function returnFunnyLoadingText() 162 { 163 var funnyLoadingTexts = [ 164 //"Locating the required gigapixels to render", 165 "Spinning up the hamster", 166 //"π × 1337% == 42", 167 //"π × 1337% != 42!", 168 //"Shovelling coal into the server", 169 "Programming the flux capacitor", 170 //"The last time I tried this the monkey didn't survive", 171 "Testing data on Timmy... ... ... We need another Timmy", 172 //"I should have had a V8 this morning", 173 //"My other load screen is much faster. You should try that one instead", 174 //"The version I have of this in testing has much funnier load screens", 175 "Warming up Large Hadron Collider", 176 "It looks like you're waiting for something to load" 177 ]; 178 return options.loadingText ? options.loadingText : (funnyLoadingTexts[Math.round(Math.random()*(funnyLoadingTexts.length-1))] + '...'); 179 }; 180 181 182 // Continuing with the variables. 183 var t = 0; 184 var ot = t; 185 var nt = t; 186 var ts = s-1; 187 188 var clickable = true; 189 var buttonclicked = false; 190 var fading = false; 191 var ajaxloading = false; 192 var autoheightdocument = 0; 193 var numericControls = new Array(); 194 var numericContainer = false; 195 var destroyed = false; 196 197 // Set obj overflow to hidden (and position to relative <strike>, if fade is enabled. </strike>) 198 obj.css("overflow","hidden"); 199 if (obj.css("position") == "static") obj.css("position","relative"); // Fixed a lot of IE6 + IE7 bugs. 200 201 // Float items to the left 202 li.css('float', 'left'); 203 204 // They doens't always put a text in the numericText. 205 // With this, if the user dont, the code will. 206 for(var i=0;i<s;i++) 207 { 208 if (optionsnumericText[i] == undefined) optionsnumericText[i] = (i+1); 209 // Same thing for ajax thingy. 210 if (optionsajax && optionsajax[i] == undefined) optionsajax[i] = false; 211 } 212 213 // Clone elements for continuous scrolling 214 if(optionscontinuous) 215 { 216 if(optionsvertical) 217 { 218 // First we create the elements, pretending AJAX is a city in Russia. 219 ul.prepend(li.filter(":last-child").clone().css("margin-top","-"+ h +"px")); 220 ul.append(li.filter(":nth-child(2)").clone()); 221 ul.height((s+1)*h); 222 } else { 223 // First we create the elements, pretending AJAX is a city in Russia. 224 ul.prepend(li.filter(":last-child").clone().css("margin-left","-"+ w +"px")); 225 ul.append(li.filter(":nth-child(2)").clone()); 226 ul.width((s+1)*w); 227 } 228 // Now, lets check if AJAX really is a city in Russia. 229 if (optionsajax) 230 { 231 // Now we move from Russia back to reallity (nothing bad about the Russians, it's just a saying in Denmark.) 232 // Starting with putting the first document after the last. 233 if (optionsajax[0]) { 234 ajaxLoad('last', 0, false, 0); 235 // ajaxLoad(0, 0, false, 0); //And this would just be a waste of brandwith. 236 } 237 // And putting the last document before the first. 238 if (optionsajax[s-1]) 239 { 240 ajaxLoad('first', (s-1), false, 0); 241 // 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. 242 ajaxLoad(ts, ts, false, 0); 243 optionsajax[s-1] = false; 244 } 245 } 246 } 247 else // <strike>Bug fix</strike> feature. 248 { 249 if(optionsvertical) ul.height(s*h); 250 else ul.width(s*w); 251 }; 252 253 // Display the controls. 254 if(options.controlsShow) 255 { 256 var controls = $('<span ' + options.controlsAttr + '></span>');
257 if (options.insertAfter) $(obj).after(controls); 258 else $(obj).before(controls); 259 260 var html = options.controlsBefore; 261 var titre = ''; 262 if(optionsnumeric) { 263 numericContainer = controls.prepend('<ol '+ optionsnumericAttr +'></ol>').children(); 264 for(var i=0;i<s;i++) 265 { 266 titre = $('#tetiere .li_tet_'+ i +' h2').html(); 267 numericControls[i] = $(document.createElement("li")) 268 .attr({'rel' : (i+1)}) 269 .html('<a href="#" title="'+ optionsnumericText[i] +' - '+titre+'"><span>'+ optionsnumericText[i] +'</span></a>') 270 .appendTo(numericContainer) 271 .click(function(){ 272 goToSlide($(this).attr('rel') - 1, true); 273 return false; 274 }); 275 }; 276 } 277 if(optionsfirstShow) { 278 var firstbutton = makecontrol(options.firstHtml, "first"); 279 } 280 if(optionslastShow) { 281 var lastbutton = makecontrol(options.lastHtml, "last"); 282 } 283 if(optionsprevNext){ 284 var nextbutton = makecontrol(options.nextHtml, "next"); 285 var prevbutton = makecontrol(options.prevHtml, "prev"); 286 } 287 }; 288 289 // Preload elements. 290 if (options.preloadAjax) 291 { 292 for (var i=0;i<=ts;i++) // Preload everything. 293 { 294 295 if (optionsajax[i]) 296 { 297 // If somethings is to be loaded, lets load it. 298 ajaxLoad(i, i, false, 0); 299 // Making sure it aint loaded again. 300 optionsajax[i] = false; 301 } 302 } 303 } 304 305 function goToSlide(i, clicked) 306 { 307 if (!destroyed) 308 { 309 if (optionsfade) 310 { 311 fadeto(i, clicked); 312 } else { 313 animate(i,clicked,true); 314 } 315 } 316 }; 317 // I go a long way to save lines of code. 318 function makecontrol(html, action) 319 { 320 var button = $(html); 321 controls.prepend(button); 322 button.click(function(){ 323 goToSlide(action, true); 324 return false; 325 }); 326 return button; 327 } 328 329 // Lets make those fast/normal/fast into some numbers we can make calculations with. 330 optionscontrolsFadeSpeed = textSpeedToNumber(optionscontrolsFadeSpeed); 331 optionsspeed = textSpeedToNumber(optionsspeed); 332 optionspause = textSpeedToNumber(optionspause); 333 optionsspeedhistory = textSpeedToNumber(optionsspeedhistory); 334 optionsfadespeed = textSpeedToNumber(optionsfadespeed); 335 // The functions do the magic. 336 function textSpeedToNumber(speed) 337 { 338 if (parseInt(speed)) var returnspeed = parseInt(speed); 339 else 340 { 341 var returnspeed = 400; 342 switch(speed) 343 { 344 case 'fast': 345 returnspeed = 200; 346 break; 347 case 'normal': 348 returnspeed = 400; 349 break; 350 case 'medium': 351 returnspeed = 400; 352 break; 353 case 'slow': 354 returnspeed = 600; 355 break; 356 } 357 } 358 return returnspeed; 359 }; 360 function runOnImagesLoaded(e,_cb) 361 { 362 // 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". 363 e.each(function() { 364 var $imgs = (this.tagName.toLowerCase()==='img')?$(this):$('img',this), 365 _cont = this, 366 i = 0, 367 _done=function() { 368 if( typeof _cb === 'function' ) _cb(_cont); 369 }; 370 371 if( $imgs.length ) { 372 $imgs.each(function() { 373 var _img = this, 374 _checki=function(e) { 375 if((_img.complete) || (_img.readyState=='complete'&&e.type=='readystatechange') ) 376 { 377 if( ++i===$imgs.length ) _done(); 378 } 379 else if( _img.readyState === undefined ) // dont for IE 380 { 381 $(_img).attr('src',$(_img).attr('src')); // re-fire load event 382 } 383 }; // _checki \\ 384 $(_img).bind('load readystatechange', function(e){_checki(e);}); 385 _checki({type:'readystatechange'}); // bind to 'load' event... 386 }); 387 } else _done(); 388 });
389 }; 390 391 // Is the file a image? (This function is not only used in the Ajaxload function) 392 function imageCheck(file) 393 { 394 var image = false; 395 396 var len = file.length; 397 var ext = file.substr(len-4, 4); 398 399 if (ext == '.jpg' || ext == '.png' || ext == '.bmp' || ext == '.gif') 400 { 401 image = true; 402 } 403 var ext = file.substr(len-5, 5); 404 if (ext == '.jpeg') 405 { 406 image = true; 407 } 408 409 return image; 410 } 411 function fadeControl (fadeOpacity,fadetime,nextcontrol) 412 { 413 if (nextcontrol) 414 { 415 var eA = nextbutton; 416 var eB = lastbutton; 417 var directionA = 'next'; 418 var directionB = 'last'; 419 var firstlastshow = optionslastShow; 420 } 421 else 422 { 423 var eA = prevbutton; 424 var eB = firstbutton; 425 var directionA = 'prev'; 426 var directionB = 'first'; 427 var firstlastshow = optionsfirstShow; 428 } 429 if (!optionscontinuous) 430 { 431 if (optionsprevNext) eA.fadeTo(fadetime, fadeOpacity, function() { if (fadeOpacity == 0) $(this).hide();}); 432 if (firstlastshow) eB.fadeTo(fadetime, fadeOpacity, function() { if (fadeOpacity == 0) $(this).hide();}); 433 if(optionscustomLink) 434 { 435 $(optionscustomLink) 436 .filter(function(index) { 437 return ($(this).attr("rel") == directionA || $(this).attr("rel") == directionB); 438 }) 439 .fadeTo(fadetime, fadeOpacity, function() { if (fadeOpacity == 0) $(this).hide();}); 440 } 441 } 442 }; 443 // Fade the controls, if we are at the end of the slide. 444 // It's all the different kind of controls. 445 function fadeControls (a,fadetime) 446 { 447 if(a==0) fadeControl (0,fadetime,false); 448 else fadeControl (1,fadetime,false); 449 450 if(a==ts) fadeControl (0,fadetime,true); 451 else fadeControl (1,fadetime,true); 452 }; 453 454 455 456 // Updating the 'current' class 457 function setCurrent(i) 458 { 459 i = parseInt((i>ts) ? i=0 : ((i<0)? i=ts: i)) + 1; 460 for(var a=0;a<numericControls.length;a++) setCurrentElement(numericControls[a], i); 461 if(optionscustomLink) setCurrentElement(optionscustomLink, i); 462 }; 463 function setCurrentElement(element,i) 464 { 465 $(element) 466 .filter(".current") 467 .removeClass("current") 468 .each(function() { 469 if ($.isFunction(optionsuncurrentFunc)){ optionsuncurrentFunc.call(this, $(this).attr("rel")); } 470 }); 471 $(element) 472 .filter(function() { 473 return $(this).attr("rel") == i; 474 }) 475 .addClass("current") 476 .each(function(index) { 477 if ($.isFunction(optionscurrentFunc)){ optionscurrentFunc.call(this, i); } 478 }); 479 }; 480 // Find out wich numericText fits the current url. 481 function filterUrlHash(t) 482 { 483 var te = 0; 484 for (var i=0;i<=s;i=i+1) if (optionsnumericText[i] == t) te = i; 485 return te; 486 }; 487 // Automaticly adjust the height, i love this function. 488 function autoheight(i, speed) 489 { 490 if (i == s) i = 0; 491 // First i run it. In case there are no images. 492 var target = li.eq(i); 493 var nheight = target.height(); 494 if (nheight != 0) setHeight(nheight, speed); 495 // Then i run it again after the images has been loaded. (If any) 496 runOnImagesLoaded(target,function(imgtarget){ 497 nheight = $(imgtarget).height(); 498 if (nheight != 0) setHeight(nheight, speed); 499 }); 500 }; 501 function setHeight(nheight, speed) 502 { 503 obj.animate( 504 { height:nheight}, 505 { 506 queue:false, 507 duration:speed, 508 easing:optionsease 509 } 510 ); 511 }; 512 // When the animation finishes (fade or sliding), we need to adjust the slider. 513 function adjust() 514 { 515 if(t>ts) t=0; 516 if(t<0) t=ts; 517 if (!optionsupdateBefore) setCurrent(t); 518 if(optionsvertical) ul.css("margin-top",(t*h*-1)); 519 else ul.css("margin-left",(t*w*-1)); 520 clickable = true; 521 if(optionshistory && buttonclicked) window.location.hash = optionsnumericText[t]; 522 if (!fading) 523 { 524 // Lets run the after animation function. 525 if ($.isFunction(optionsafterAniFunc)){optionsafterAniFunc.call(li.eq(t) , t + 1);} 526 } 527 }; 528 // Convert the direction into a usefull number. 529 function filterDir(dir, ot) 530 { 531 var nt = t; // i dont want to mess with the 't' variable. 532 switch(dir) 533 { 534 case "next": 535 nt = (ot>=ts) ? (optionscontinuous ? nt+1 : ts) : nt+1; 536 break; 537 case "prev": 538 nt = (t<=0) ? (optionscontinuous ? nt-1 : 0) : nt-1; 539 break; 540 case "first": 541 nt = 0; 542 break; 543 case "last": 544 nt = ts; 545 break; 546 default: 547 nt = parseInt(dir); 548 break; 549 }; 550 return nt; 551 }; 552 // Load a ajax document (or i image) into a list element. 553 // If testing this locally (loading everything from a harddisk instead of the internet), it may not work. 554 // But then try to upload it to a server, and see it shine. 555 function ajaxLoad(i, l, adjust, speed) 556 { 557 var targetslide = false; 558 if (parseInt(i) || i == 0) targetslide = li.eq(i); 559 else 560 { 561 if (i == 'last') targetslide = $('li:last', obj); 562 else targetslide = $('li:first', obj); 563 } 564 // What speed should the autoheight function animate with? 565 var ajaxspeed = (fading) ? (!optionscrossFade ? parseInt(optionsfadespeed * (2/5)) : optionsfadespeed) : speed; 566 // The script itself is not using the 'tt' variable. But a custom function can use it. 567 var tt = l + 1; 568 if (imageCheck(optionsajax[l])) 569 { 570 // Load the image. 571 targetslide.html(' ').append($(new Image()).attr('src', optionsajax[l]));
572 // When the document is ready again, we launch a autoheight event. 573 runOnImagesLoaded(targetslide,function(img){ 574 var target = $(img).children(); 575 // If the image is to wide, shrink it. 576 var width = target.width(); 577 var height = target.height(); 578 target.attr({'oldheight' : height, 'oldwidth' : width}); 579 if (width > w) target.animate({ width: w, height: (height/width)*w}, 0); 580 // If we want, we can launch a function here. 581 if ($.isFunction(optionsimgAjaxFunction)){optionsimgAjaxFunction.call($(img), tt);} 582 // Then do the autoheight. 583 if (optionsautoheight && adjust) autoheight(t, ajaxspeed); 584 }); 585 } 586 else 587 { 588 589 // Load the document into the list element. 590 targetslide.load(optionsajax[l], function(response, status, xhr) { 591 if (status == "error" || !$(this).html()) $(this).html("Sorry but there was an error: " + (xhr.status ? xhr.status: 'no content') + " " + xhr.statusText); 592 // If we want, we can launch a function here. 593 if (status != "error" && $.isFunction(optionsdocAjaxFunction)){optionsdocAjaxFunction.call($(this), tt);} 594 // Lets adjust the height, i don't care if there's an error or not. 595 // var nheight = $(this).height(); // Why did i put that there??? Delete this comment when reason is found. 596 if (optionsautoheight && adjust) autoheight(l, ajaxspeed); // This is theoreticly a bug-fix, if there are no images in the loaded document. 597 }); 598 } 599 }; 600 // It's not only a slider, it can also fade from slide to slide. 601 function fadeto(i, clicked) 602 { 603 if (i != t && !destroyed) // We doesn't want something to happen all the time. The URL can change a lot, and cause som "flickering". 604 { 605 if (clickable) 606 { 607 ajaxloading = false; 608 // Stop auto if cliked. 609 if(clicked) clearTimeout(timeout); 610 // Update the current class of the buttons. 611 if (optionsupdateBefore) setCurrent(filterDir(i, ot)); 612 // Only clickable if not clicked. 613 clickable = !clicked; 614 // Setting the speed. 615 var speed = (!clicked && !optionsauto && optionshistory) ? optionsfadespeed * (optionsspeedhistory / optionsspeed) : optionsfadespeed; 616 var ll = filterDir(i, ot); 617 // Lets make sure that the target actually exists. 618 if(ll>ts) ll=0; 619 if(ll<0) ll=ts; 620 // Lets make sure the prev/next buttons also fade. 621 if(optionscontrolsFade) fadeControls (ll,optionscontrolsFadeSpeed); 622 // Lets adjust the height, but not if the ajax document isn't loaded. 623 if (optionsautoheight) 624 { 625 if (optionsajax) 626 { 627 // If Ajax is enabled 628 if (!optionsajax[ll]) autoheight(ll,optionsfadespeed); // we only want to change the height, if the document we are fading to, is allready loaded. 629 } 630 else autoheight(ll,optionsfadespeed); // The height animation takes the full lenght of the fade animation (fadein + fadeout if it's not crossfading). 631 } 632 // Define the target. 633 var target = li.eq(ll); 634 // So lets run the function. 635 if ($.isFunction(optionsbeforeAniFunc)){optionsbeforeAniFunc.call(target, ll + 1);} 636 // Crossfading? 637 if (optionscrossFade) 638 { 639 // I clone the target, and fade it in, then hide the cloned element while adjusting the slider to show the real target. 640 // I dont hide it right away, because that breaks the autoheight function, and the function that auto-resizes ajax-loaded images. 641 var fadeIntarget = target.clone().prependTo(obj).css({'z-index' : '100000', 'position' : 'absolute', 'list-style' : 'none', 'top' : '0', 'left' : '0'});
642 // Maybe we need to load some content into it first? 643 if (optionsajax[ll]) 644 { 645 // I have to load the Ajax-content into the target clone, and the target itself. 646 // First the target clone. 647 ajaxLoad(0, ll, false, speed); 648 // Then the target. 649 if (imageCheck(optionsajax[ll])) // Weird bugs, weird fixes. But this works. 650 { 651 ajaxLoad(ll+1, ll, false, speed); 652 runOnImagesLoaded(li.eq(ll+1),function(){ 653 if (optionsautoheight) autoheight(ll, optionsfadespeed); 654 }); 655 } 656 else 657 { 658 ajaxLoad(ll+1, ll, true, speed); 659 } 660 optionsajax[ll] = false; 661 } 662 // Lets fade it in. 663 fadeIntarget.hide().fadeIn(optionsfadespeed, function() { 664 // So the animate function knows what to do. 665 clickable = true; 666 fading = true; 667 animate(i,false,false); // Moving to the correct place. 668 // Removing it again, if i dont, it will just be a pain in the .... 669 $(this).remove(); 670 if(optionshistory && clicked) window.location.hash = optionsnumericText[t]; // It's just one line of code, no need to make a function of it. 671 // Lets put that variable back to the default (and not during animation) value. 672 fading = false; 673 // Now run that after animation function. 674 // We already got the target and the slider number from earlier. 675 // So lets run the function. 676 if ($.isFunction(optionsafterAniFunc)){optionsafterAniFunc.call(target, ll + 1);} 677 });
678 } 679 else 680 { 681 // fadeOut and fadeIn. 682 var fadeinspeed = parseInt((speed)*(3/5)); 683 var fadeoutspeed = speed - fadeinspeed; 684 // 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. 685 var noncrossfadetargets = li.children(); 686 noncrossfadetargets.stop().fadeTo(fadeoutspeed, 0.0001, function(){ 687 // So the animation function knows what to do. 688 clickable = true; 689 fading = true; 690 animate(i,false,false); // Moving to the correct place. 691 // Only clickable if not clicked. 692 clickable = !clicked; 693 // Now, lets fade the slider back in. 694 // Got no idea why the .add(li) is nesecary, but it is. (If it isn't there, the first slide never fades back in). 695 noncrossfadetargets.add(li).stop().fadeTo(fadeinspeed, 1, function(){ 696 if(optionshistory && clicked) window.location.hash = optionsnumericText[t]; // It's just one line of code, no need to make a function of it. 697 clickable = true; 698 fading = false; 699 // Now run that after animation function. 700 // We already got the target and the slider number from earlier. 701 // So lets run the function. 702 if ($.isFunction(optionsafterAniFunc)){optionsafterAniFunc.call(target, ll + 1);} 703 }); 704 });
705 } 706 } 707 } 708 }; 709 function animate(dir,clicked,time) // (Direction, did the user click something, is this to be done in >1ms?) 710 { 711 if (clickable && !destroyed && (filterDir(dir, ot) != t || init)) 712 { 713 ajaxloading = false; 714 clickable = (!clicked && !optionsauto) ? true : options.clickableAni; 715 // to the adjust function. 716 buttonclicked = clicked; 717 ot = t; 718 t = filterDir(dir, ot); 719 if (optionsupdateBefore) setCurrent(t); 720 // Calculating the speed to do the animation with. 721 var diff = Math.sqrt(Math.abs(ot-t)); 722 var speed = parseInt(diff*optionsspeed); 723 if (!clicked && !optionsauto) speed = parseInt(diff*optionsspeedhistory); // Auto:true and history:true doens't work well together, and they ain't supposed to. 724 if (!time) speed = 0; 725 726 // Ajax begins here 727 // I also these variables in the below code (running custom function). 728 var i = t; 729 if(t>ts) i=0; 730 if(t<0) i=ts; 731 if (optionsajax) 732 { 733 // Loading the target slide, if not already loaded. 734 if (optionsajax[i]) 735 { 736 ajaxLoad(i, i, true, speed); 737 optionsajax[i] = false; 738 ajaxloading = true; 739 } 740 // It can look stupid the script scroll over some not-loaded slides. Therefore, they are loaded. 741 // It can produce some heavy load, so the script wont do it, it it's more than 10 slides. 742 if (!fading) 743 { 744 // I dont like copypasting the same code, but this is the most efficient way i can think of atm. 745 var countajax = 0; 746 if (ot > t) 747 { 748 for (a = t; a <= ot; a++) 749 { 750 if (a<=ts && a>=0) 751 { 752 if (optionsajax[a]) 753 { 754 ajaxLoad(a, a, false, speed); 755 optionsajax[a] = false; 756 countajax++; 757 } 758 } 759 if (countajax == 10) a = ot; 760 } 761 } 762 else 763 { 764 for (a = ot; a <= t; a++) 765 { 766 if (a<=ts && a>=0) 767 { 768 if (optionsajax[a]) 769 { 770 ajaxLoad(a, a, false, speed); 771 optionsajax[a] = false; 772 countajax++; 773 } 774 } 775 if (countajax == 10) a = t; 776 } 777 } 778 } 779 // Then we have to preload the next one. 780 if (i + 1 <= ts) 781 { 782 if (optionsajax[i + 1]) 783 { 784 ajaxLoad(i + 1, i + 1, false, 0); 785 optionsajax[i + 1] = false; 786 } 787 } 788 // And the previous one. 789 if (i - 1 >= 0) 790 { 791 if (optionsajax[i - 1]) 792 { 793 ajaxLoad(i - 1, i - 1, false, 0); 794 optionsajax[i - 1] = false; 795 } 796 } 797 } 798 // Ajax ends here 799 if (!fading) 800 { 801 // Lets run the before animation function. 802 if ($.isFunction(optionsbeforeAniFunc)){ 803 optionsbeforeAniFunc.call(li.eq(i), i + 1); 804 if (t == -1 || t == s) optionsbeforeAniFunc.call(ul.children("li").eq((t == -1) ? 0 : -1), i + 1); 805 } 806 807 } 808 // Start animation. 809 if(!optionsvertical) { 810 if (optionsautoheight && !fading && !ajaxloading) autoheight(t, speed); 811 var p = (t*w*-1); 812 ul.animate( 813 { marginLeft: p}, 814 { 815 queue:false, 816 duration:speed, 817 easing:optionsease, 818 complete:adjust 819 } 820 ); 821 } else { 822 p = (t*h*-1); 823 ul.animate( 824 { marginTop: p }, 825 { 826 queue:false, 827 duration:speed, 828 easing:optionsease, 829 complete:adjust 830 } 831 ); 832 }; 833 // End animation. 834 835 // Fading the next/prev/last/first controls in/out if needed. 836 if(optionscontrolsFade) 837 { 838 var fadetime = optionscontrolsFadeSpeed; 839 if (!clicked && !optionsauto) fadetime = (optionsspeedhistory / optionsspeed) * optionscontrolsFadeSpeed; 840 if (!time) fadetime = 0; 841 if (fading) fadetime = parseInt((optionsfadespeed)*(3/5)); 842 fadeControls (t,fadetime); 843 } 844 845 // Stopping auto if clicked. 846 if(clicked) clearTimeout(timeout); 847 // Continuing if not clicked. 848 if(optionsauto && dir=="next" && !clicked){ 849 timeout = startAuto(optionspause + optionsspeed); 850 }; 851 // Stop init, first animation is done. 852 init = false; //nasty workaround, but it works. 853 }; 854 }; 855 // init 856 var timeout; 857 858 // Starting auto. 859 if(optionsauto) timeout = startAuto(optionspause); 860 function startAuto(pause) 861 { 862 return setTimeout(function(){ 863 goToSlide("next", false); 864 },pause); 865 } 866 if (optionscustomLink) // customLinks. Easy to make, great to use. 867 { 868 // Using live, that way javascript ajax-loaded buttons and javascript generated content will work. 869 $(optionscustomLink).live('click', function() { 870 var a = $(this).attr('rel'); 871 if (a) doExternalInput(a); 872 return false; 873 }); 874 } 875 obj.bind('sudoSliderEvent', function(e, a) { 876 doExternalInput(a); 877 }); 878 function doExternalInput(a) 879 { 880 // Check for special events 881 if (a == 'stop') clearTimeout(timeout) 882 else if (a == 'start') 883 { 884 timeout = startAuto(optionspause);
885 optionsauto = true; 886 } 887 else if (a == 'block') clickable = false; // Simple, beautifull. 888 else if (a == 'unblock') clickable = true; // -||- 889 else if (a == 'action') alert('The slider just performed an action'); // Kind of an easter egg. When explaining how to use "actions", i use '$("#slider").sudoSlider("action");', so i thought that the useless example should actually do something. 890 else if (a == 'destroy') // For good. 891 { 892 // First, i remove the controls. 893 controls.remove(); // that's it. 894 // Now to set a variable, so nothing is run. 895 destroyed = true; // No animation, no fading, no clicking from now. 896 // Then remove the customLink bindings: 897 $(optionscustomLink).die("click"); 898 // Now remove the "continuous clones". 899 if (optionscontinuous) 900 { 901 ul.children("li").eq(0).remove(); 902 ul.children("li").eq(-1).remove(); 903 } 904 } 905 // The general case. 906 // That means, typeof(a) == numbers and first,last,next,prev 907 // I dont make any kind of input validation, meaning that it's quite easy to break the script with non-valid input. 908 else if (clickable) goToSlide((a == parseInt(a)) ? a - 1 : a, true); 909 }; 910 911 912 // Lets make those bookmarks and back/forward buttons work. 913 if (optionshistory) { 914 // Going to the correct slide at load. 915 $.address.init(function(e) { 916 var i = filterUrlHash(e.value); 917 animate(i,false,false); 918 }) 919 // Sliding/fading to the correct slide, on url change. 920 .change(function(e) { 921 var i = filterUrlHash(e.value); 922 if (i != t) goToSlide(i, false); 923 }); 924 } 925 // The startSlide setting only require one line of code. And here it is: 926 else if (optionsstartSlide) animate(optionsstartSlide - 1,false,false); 927 // doing it anyway. good way to fix bugs. 928 // And i only preload the next and previous slide after init (which this is). So i'm doing it. 929 // + 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. 930 else animate(0,false,false); 931 }); 932 } 933 }; 934})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.