1/** 2 * Slider Kit v1.9.2 - Sliding contents with jQuery 3 * http://www.kyrielles.net/sliderkit 4 * 5 * Copyright (c) 2010-2012 Alan Frog 6 * Licensed under the GNU General Public License 7 * See <license.txt> or <http://www.gnu.org/licenses/> 8 * 9 * Requires: jQuery v1.3+ <http://jquery.com/> 10 * 11 * --------------------------------- 12 * This file is part of Slider Kit jQuery plugin. 13 * 14 * Slider Kit is free software: you can redistribute it and/or modify 15 * it under the terms of the GNU General Public License as published by 16 * the Free Software Foundation, either version 3 of the License, or 17 * (at your option) any later version. 18 * 19 * Slider Kit is distributed in the hope that it will be useful, 20 * but WITHOUT ANY WARRANTY; without even the implied warranty of 21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 * GNU General Public License for more details. 23 * --------------------------------- 24 */ 25 26(function($){ 27 28 SliderKit = function() { 29 30 var self = this; 31 32 this._init = function( element, options ) { 33 34 /*--------------------------------- 35 * Basic settings 36 *---------------------------------*/ 37 38 // Passed in options and default options are mixed 39 this.options = $.extend({}, this._settings, options); 40 41 // CSS class names 42 this.cssNames = { 43 selected: this.options.cssprefix+"-selected", 44 panel: this.options.cssprefix+"-panel", 45 panels: this.options.cssprefix+"-panels", 46 panelActive: this.options.cssprefix+"-panel-active", 47 panelOld: this.options.cssprefix+"-panel-old", 48 panelsWrapper: this.options.cssprefix+"-panels-wrapper", 49 nav: this.options.cssprefix+"-nav", 50 navClip: this.options.cssprefix+"-nav-clip", 51 navBtn: this.options.cssprefix+"-nav-btn", 52 navPrev: this.options.cssprefix+"-nav-prev", 53 navNext: this.options.cssprefix+"-nav-next", 54 btnDisable:this.options.cssprefix+"-btn-disable", 55 btnPause: this.options.cssprefix+"-pause-btn", 56 goPrev: this.options.cssprefix+"-go-prev", 57 goNext: this.options.cssprefix+"-go-next", 58 playBtn: this.options.cssprefix+"-play-btn", 59 goBtns: this.options.cssprefix+"-go-btn" 60 }; 61 62 // Save the element reference 63 this.domObj = $( element ); // The main container DOM element 64 65 // Getting main elements (panels & nav) 66 this.panels = $("."+this.cssNames.panel, this.domObj); 67 this.allItems = this.panels.size(); 68 this.nav = $("."+this.cssNames.nav, this.domObj); 69 this.navClip = $("."+this.cssNames.navClip, this.nav); 70 71 // Check if there is any reason to go further 72 this.arePanels = this.allItems > 0 ? 1 : 0; 73 this.isNavClip = this.navClip.size() > 0 ? 1 : 0; 74 75 if( !this.arePanels && !this.isNavClip ){ 76 this._errorReport( "Error #01", this.options.debug, 1 ); 77 } 78 79 this.domObjHeight = this.domObj.height(); 80 this.domObjWidth = this.domObj.width(); 81 82 // Check if there is a height value (unless 'freeheight' setting is true) 83 if( !this.domObjHeight && !this.options.freeheight ){ 84 this.domObjHeight = this.options.height; 85 this.domObj.css ( 'height', this.domObjHeight ); 86 this._errorReport( "Error #02", this.options.debug, 0 ); 87 } 88 // Or a width value 89 if( !this.domObjWidth ){ 90 this.domObjWidth = this.options.width; 91 this.domObj.css ( 'width', this.domObjWidth ); 92 this._errorReport( "Error #02", this.options.debug, 0 ); 93 } 94 95 // By default, the widget should be hidden via CSS. Then shown only if javascript is available : 96 this.domObj.css( 'display', 'block' ); 97 98 // Variables that will be needed all over the script 99 this.currId = 0; 100 this.prevId = 0; 101 this.newId = 0; 102 this.currPanel = null; 103 this.prevPanel = 0; 104 this.prevPanelStill = 0; 105 this.firstTime = 1; 106 this.scrollActive = 0; 107 this.isPlaying = null; 108 this.changeOngoing = false; 109 this.currLine = 1; 110 this.animating = false; 111 this.panelAnteFns = new Array; 112 this.panelPostFns = new Array; 113 this.navAnteFns = new Array; 114 this.navPostFns = new Array; 115 this.runningScope = this.nav; 116 117 // Nav builder 118 if(this.isNavClip){ 119 this._buildNav(); 120 } 121 122 // Controls builder 123 this._buildControls(); 124
125 // Panels wrapper : this is only for internal code usage; 126 // It allows a nice sliding effect in the panels container 127 if( this.arePanels ){ 128 this.panelsBag = $("."+ this.cssNames.panels, this.domObj); 129 if( this.options.panelfx == "sliding" ){ 130 this._wrapPanels(); 131 } 132 } 133 134 /*--------------------------------- 135 * Navigation settings 136 *---------------------------------*/ 137 138 // In carousel mode (no panels), mousewheel and autoscroll should move lines instead of thumbnails. This behaviour is also set for 'navpanelautoswitch' option. 139 this.lineScrollDo = !this.arePanels ? 1 : 0; 140 141 // Mousewheel navigation 142 if(this.options.mousewheel){ 143 this.domObj.mousewheel(function(event, delta){ 144 delta > 0 ? self.stepBackward() : self.stepForward(); 145 return false; 146 }); 147 } 148 149 // Keyboard navigation (beta) 150 if( this.options.keyboard ){ 151 this.domObj.keyup(function(event){ 152 // slide left 153 if(event.keyCode == 37){ 154 self.stepBackward(); 155 } 156 // slide right 157 else if (event.keyCode == 39){ 158 self.stepForward(); 159 } 160 }); 161 } 162 163 // One-click navigation 164 if(this.options.panelclick && this.arePanels){ 165 this.panelsBag.click(function(){ 166 self.stepForward(); 167 return false; 168 }); 169 } 170 171 // Sarting id 172 this.startId = this.options.start >= this.allItems ? this.allItems-1 : this.options.start < 0 ? 0 : this.options.start; 173 174 /*--------------------------------- 175 * Add-ons 176 *---------------------------------*/ 177 178 // Counter 179 if( this.options.counter ){ 180 try{ this.Counter(); } 181 catch( err ){ 182 this._errorReport(err, this.options.debug, 0); 183 } 184 } 185 186 // ImageFx 187 if( this.imageFx ){ 188 try{ this.imageFx(); } 189 catch( err ){ 190 this._errorReport(err, this.options.debug, 0); 191 } 192 } 193 194 // DelayCaptions 195 if( this.options.delaycaptions ){ 196 try{ this.DelayCaptions( this.options.delaycaptions ); } 197 catch( err ){ 198 this._errorReport(err, this.options.debug, 0); 199 } 200 } 201 202 // Slide for the first time 203 this.changeWithId( this.startId, null ); 204 205 /*--------------------------------- 206 * Time options 207 *---------------------------------*/ 208 209 // Auto-scrolling starter 210 if(this.options.auto){ 211 this.autoScrollStart(); 212 213 // Stops autoScrolling when mouse is over the slider content 214 this._autoScrollHoverStop(); 215 } 216 217 // Timer load 218 if( this.options.timer ){ 219 try{ this.Timer( this.options.timer ); } 220 catch( err ){ 221 this._errorReport(err, this.options.debug, 0); 222 } 223 } 224 225 /*--------------------------------- 226 * Running scope 227 *---------------------------------*/ 228 if( this.arePanels && !this.options.fastchange ){ 229 this.runningScope = this.domObj.find( '.' + this.cssNames.panels, '.' + this.cssNames.nav ); 230 } 231 232 // return this so we can chain/use the bridge with less code. 233 return this; 234 }; 235 236 this._settings = { 237 cssprefix:"sliderkit", 238 width:500, 239 height:350, 240 start:0, 241 auto:true, 242 autospeed:2500, 243 autostill:false, 244 mousewheel:false, 245 keyboard:false, 246 circular:false, 247 shownavitems:5, 248 navitemshover:false, 249 navclipcenter:false, 250 navcontinuous:false, 251 navscrollatend:false, 252 navpanelautoswitch:true, 253 navfx:"sliding", 254 navfxbefore:function(){}, 255 navfxafter:function(){}, 256 scroll:null, 257 scrollspeed:600, 258 scrolleasing:null, 259 panelfx:"fading", 260 panelfxspeed:700, 261 panelfxeasing:null, 262 panelfxfirst:"none", 263 panelfxbefore:function(){}, 264 panelfxafter:function(){}, 265 panelbtnshover:false, 266 panelclick:false, 267 verticalnav:false, 268 verticalslide:false, 269 tabs:false, 270 freeheight:false, 271 fastchange:true, 272 counter:false, 273 delaycaptions:false, 274 timer:false, 275 imagefx:false, 276 debug:false 277 }; 278 279 this._errorReport = function( errorCode, debug, stop ){ 280 if(debug){ 281 alert("Slider Kit error!\nMessage = "+errorCode+" (see doc for details)\nElement id = "+this.domObj.attr("id")+"\nElement class = "+this.domObj.attr("class")); 282 } 283 if(stop){ 284 return false; 285 } 286 }; 287 288 this._autoScrollHoverStop = function(){ 289 290 // Stop auto-scrolling when mouse goes over the slider 291 if( !this.isPlayBtn && !this.options.autostill ){ 292 this.domObj.hover( 293 function(){ 294 if( self.isPlaying!=null ){ 295 self.autoScrollStop(); 296 } 297 }, 298 function(){ 299 self.autoScrollStart(); 300 } 301 ); 302 } 303 304 // Restart auto-scrolling on mouse leave if 'autostill' is on 305 if( this.options.autostill ){ 306 this.domObj.mouseleave(function(){ 307 if( self.isPlaying == null ){ 308 self.autoScrollStart(); 309 } 310 }); 311 } 312 }; 313 314 this._buildNav = function() { 315 316 this.navUL = $("ul", this.navClip); 317 this.navLI = $("li", this.navUL); 318 this.navLINum = this.navLI.size(); 319 320 // Check if nav size is equal to panels size (only if there are panels) 321 if(this.arePanels && (this.navLINum != this.allItems) && this.nav.size() == 1){ 322 this._errorReport("Error #03", this.options.debug, 1); 323 } 324 325 // If Slider Kit is used as a tabs menu, the nav scroll becomes useless (well, for now...) 326 if(this.options.tabs){ 327 this.options.shownavitems = this.allItems; 328 } 329 330 // Else we start initializing the carousel
331 else{ 332 // LI margins function: returns the <li> tag margins value in pixels 333 function getLImargin(attr){ 334 attrVal = self.navLI.css(attr); 335 if(attrVal!="auto" && attr!="" && attr!="0px"){ 336 return parseInt(attrVal); 337 } 338 else return 0; 339 } 340 341 // Nav elements size 342 var navSize = this.options.verticalnav ? this.nav.height() : this.nav.width(); 343 var navLIWidth = this.navLI.outerWidth(true); // padding + margin + border 344 var navLIHeight = this.navLI.outerHeight(true); 345 var navLIextHMarg = getLImargin("margin-left") + getLImargin("margin-right"); 346 var navLIextVMarg = getLImargin("margin-top") + getLImargin("margin-bottom"); 347 348 // bugfix 2011 01 13 349 this.allItems = this.navLINum; 350 if( this.options.shownavitems > this.allItems ){ 351 this.options.shownavitems = this.navLINum; 352 } 353 354 this.navLIsize = this.options.verticalnav ? navLIHeight : navLIWidth; 355 this.navULSize = this.navLIsize * this.navLINum; 356 this.navClipSize = (this.options.shownavitems * this.navLIsize) - (this.options.verticalnav ? navLIextVMarg : navLIextHMarg);// Removes the item side margins to center the nav clip 357 358 // CSS attributes for position/height values 359 this.cssPosAttr = this.options.verticalnav ? "top" : "left"; 360 var cssSizeAttr = this.options.verticalnav ? "height" : "width"; 361 var cssSizeAttrr = this.options.verticalnav ? "width" : "height"; 362 363 // Setting height and width values(px) to Clip, UL & LI tags 364 this.navLI.css({width:this.navLI.width(), height:this.navLI.height()}); 365 this.navUL.css(cssSizeAttr, this.navULSize+"px"); 366 this.navClip.css({width:this.options.verticalnav ? navLIWidth : this.navClipSize, height:this.options.verticalnav ? this.navClipSize : navLIHeight}); 367 368 // Center the navclip in the nav container 369 if(this.options.navclipcenter){ 370 this.navClip.css(this.cssPosAttr,( navSize - this.navClipSize)/2 ).css("margin", "0"); 371 } 372 373 // Check if linescroll is necessary 374 // The nav scrolling is required only if the number of items is greater than the 'visible' param. 375 if( this.allItems > this.options.shownavitems ){ 376 this.scrollActive = true; 377 378 // Correcting a potentially 'this.options.scroll' wrong value 379 if(this.options.scroll == null || this.options.scroll < 0 || this.options.scroll > this.allItems){ 380 this.options.scroll = this.options.shownavitems; 381 } 382 383 } 384 385 // bugfix 2011 01 13 386 // Nav Buttons 387 this.navBtns = $( '.' +this.cssNames.navBtn, this.nav ); 388 if( this.navBtns.size() > 0 ){ 389 this._buildNavButtons(); 390 } 391 } 392 393 // Nav <li> links mouse event 394 if(this.options.navitemshover && this.arePanels){ 395 this.navLI.mouseover(function(){ 396 self.changeWithId(getIndex(this, "li"), $(this)); 397 }); 398 } 399 else if(this.arePanels || this.options.navscrollatend){ 400 this.navLI.click(function(){ 401 self.changeWithId(getIndex(this, "li"), $(this)); 402 return false; 403 }); 404 } 405 406 // Get an item index 407 function getIndex(item, tag){ 408 return $(tag, $(item).parent()).index(item); 409 } 410 411 }; 412 413 this._buildNavButtons = function() { 414 415 // bugfix 2011 01 13 416 if( this.scrollActive ){ 417 this.scrollBtns = true; 418 this.navBtnPrev = $("."+this.cssNames.navPrev, this.nav); 419 this.navBtnNext = $("."+this.cssNames.navNext, this.nav); 420 this.navBtns.removeClass( this.cssNames.btnDisable ); 421 422 // Nav Buttons click event 423 this.navBtnPrev.click(function(){ 424 self.navPrev(); 425 return false; 426 }); 427 this.navBtnNext.click(function(){ 428 self.navNext(); 429 return false; 430 }); 431 432 // Nav Buttons mousedown/up events 433 if(this.options.navcontinuous){ 434 this.navBtnPrev.mouseover(function(){ 435 self.navPrev(true); 436 }); 437 this.navBtnNext.mouseover(function(){ 438 self.navNext(true); 439 }); 440 this.navBtns.mouseout(function(){ 441 self.navStopContinuous(); 442 }); 443 } 444 445 // Disable first button if not circular 446 if( !this.options.circular ){ 447 this.navBtnPrev.addClass(this.cssNames.btnDisable); 448 } 449 } 450 else{ 451 this.navBtns.addClass( this.cssNames.btnDisable ); 452 } 453 454 }; 455
456 this._getNavPos = function() { 457 this.navPos = this.options.verticalnav ? this.navUL.position().top : this.navUL.position().left; 458 this.LIbefore = Math.ceil( Math.abs(this.navPos) / this.navLIsize ); 459 this.LIafter = Math.floor(( this.navULSize - Math.abs(this.navPos) - this.navClipSize) / this.navLIsize ); 460 if(this.LIafter < 0){ 461 this.LIafter = 0; 462 } 463 }; 464 465 this._buildControls = function() { 466 467 this.playBtn = $("."+this.cssNames.playBtn, this.domObj); 468 this.gBtns = $("."+this.cssNames.goBtns, this.domObj); 469 470 this.isPlayBtn = this.playBtn.size() > 0 ? 1 : 0; 471 this.goBtns = this.gBtns.size() > 0 ? 1 : 0; 472 473 // Play button 474 if( this.isPlayBtn ){ 475 476 // If autoscroll is active, the play button is set to 'pause' mode 477 if( this.options.auto ){ 478 this.playBtn.addClass(this.cssNames.btnPause); 479 } 480 481 // Button mouse event 482 this.playBtn.click(function(){ 483 if(self.playBtn.hasClass(self.cssNames.btnPause)){ 484 self.playBtnPause(); 485 } 486 else{ 487 self.playBtnStart(); 488 } 489 return false; 490 }); 491 } 492 493 // Go buttons (prev/next) 494 if( this.goBtns ){ 495 this.goBtnPrev = $("."+this.cssNames.goPrev, this.domObj); 496 this.goBtnNext = $("."+this.cssNames.goNext, this.domObj); 497 498 // Show/hide buttons on panel mouseover 499 if(this.options.panelbtnshover){ 500 this.gBtns.hide(); 501 $("."+this.cssNames.panels, this.domObj).hover( 502 function(){ 503 self.gBtns.fadeIn(); 504 }, 505 function(){ 506 self.gBtns.fadeOut(); 507 } 508 ); 509 } 510 511 // Button click binding 512 this.goBtnPrev.click(function(){ 513 self.stepBackward($(this)); 514 return false; 515 }); 516 this.goBtnNext.click(function(){ 517 self.stepForward($(this)); 518 return false; 519 }); 520 } 521 }; 522 523 this._wrapPanels = function(){ 524 if( $( '.' + this.cssNames.panelsWrapper, this.domObj ).size() == 0 ){ 525 this.panels.wrapAll( '<div class="' + this.cssNames.panelsWrapper + '"></div>' ); 526 this.panelsWrapper = $( '.' + this.cssNames.panelsWrapper, this.panelsBag ); 527 this.panelsWrapper.css( 'position', 'relative' ); 528 } 529 }; 530 531 this._change = function( eventSrc, scrollWay, goToId, lineScrolling, stopAuto ) { 532 533 // If there is a play button + auto-scrolling running 534 if( stopAuto && this.isPlaying!=null ){ 535 if( this.isPlayBtn ){ 536 this.playBtnPause(); 537 } 538 if( this.options.autostill ){ 539 self.autoScrollStop(); 540 } 541 } 542 543 // Don't go further if the side is reached and carousel isn't circular 544 // The slide is stopped if the button is disable 545 if(eventSrc){ 546 if(eventSrc.hasClass(this.cssNames.btnDisable)){ 547 return false; 548 } 549 } 550 551 // By default, user action is blocked when nav is being animated. This to prevent the function calculation to go mad when the user is switching the items too quickly. 552 // This security applies on panels too. However it can be removed using the 'fastchange' option. 553 var stopGoing = 0; 554 var running = $( ':animated', this.runningScope ).size() > 0 ? 1 : 0; 555 556 if( !running && !this.animating ){ 557 this.prevId = this.currId; 558 559 // Increment the current id, only if linescrolling isn't required 560 if(goToId == null && !lineScrolling){ 561 this.currId = scrollWay == "-=" ? this.currId+1 : this.currId-1; 562 } 563 // Else if an id is given, we take it 564 else if(goToId != null){ 565 goToId = parseInt(goToId);// make sure it's a number 566 this.currId = goToId < 0 ? 0 : goToId > this.allItems-1 ? this.allItems-1 : goToId;// make sure it's in the nav range 567 var checkIdRange = eventSrc ? eventSrc.parent().parent().hasClass(this.cssNames.navClip) ? false : true : true; 568 } 569 570 // If panel buttons exist, we activate them 571 if(this.goBtns){ 572 this.gBtns.removeClass(this.cssNames.btnDisable); 573 } 574 575 // If the carousel isn't circular the controls must be hidden when sides are reached 576 if(!this.options.circular){ 577 // Top/left side is reached 578 if(this.currId == -1){ 579 this.currId = 0; 580 stopGoing = 1; 581 } 582 if(this.currId == 0 && this.goBtns){ 583 this.goBtnPrev.addClass(this.cssNames.btnDisable); 584 } 585 586 // Bottom/right side is reached 587 if(this.currId == this.allItems){ 588 this.currId = this.allItems-1; 589 stopGoing = 1; 590 } 591 592 if(this.currId == this.allItems-1){ 593 if(this.options.auto){ 594 this.autoScrollStop(); 595 } 596 if(this.goBtns){ 597 this.goBtnNext.addClass(this.cssNames.btnDisable); 598 } 599 } 600 } 601 // Otherwise if there is no scroll required, this.currId must be reset when sides are reached 602 else if(!this.scrollActive){ 603 if(this.currId == this.allItems){ 604 this.currId = 0; 605 } 606 if(this.currId == -1){ 607 this.currId = this.allItems-1; 608 } 609 } 610 611 // If the slide function isn't triggered from a nav LI event, we must check if the line must be scrolled or not 612 if( this.scrollActive && !stopGoing ){ 613 this._setNavScroll( lineScrolling, scrollWay, checkIdRange ); 614 } 615 616 // Highlight selected menu 617 if( this.isNavClip ){
618 this.selectThumbnail(this.currId); 619 } 620 621 // Switch to the next panel 622 // Note: if 'navpanelautoswitch' option is false, the panels won't switch when line is scrolling 623 if( ! (lineScrolling && !this.options.navpanelautoswitch) ){ 624 if( this.arePanels ){ 625 this._animPanel( this.currId, scrollWay ); 626 } 627 } 628 629 // First time cancel 630 if( this.firstTime ){ 631 this.firstTime = 0; 632 } 633 634 } // else > be patient, the line scroll is running ! 635 }; 636 637 this._setNavScroll = function( lineScrolling, scrollWay, checkIdRange ) { 638 639 // Get the current nav position 640 this._getNavPos(); 641 642 var triggerLineScroll = lineScrolling ? true : false; 643 var jumpToId = 0; 644 645 // No line scrolling required yet: we are going to check the current item position to determine if line scrolling is needed or not. 646 if( ! lineScrolling ){ 647 // Line scrolling will happen only if navclip sides are reached 648 // Number of items from the clip sides: 649 var idFromClipStart = Math.abs(this.currId+1 - this.LIbefore); 650 var idToClipEnd = this.options.shownavitems - idFromClipStart +1; 651 var currIdOnEdge = this.currId == 0 || this.currId == this.allItems-1 ? 1 : 0; 652 653 // If 'navscrollatend' option is activated, the line will scroll when navclip edges are reached (except if currId is the first or last item of the nav) 654 if( (this.options.navscrollatend && (idToClipEnd == 1 || idFromClipStart == 1)) && !this.firstTime && !currIdOnEdge ){ 655 jumpToId = this.options.scroll - 1; 656 triggerLineScroll = true; 657 } 658 659 // Else the line will scroll when currId is out of the navclip range by -1 or +1 660 if(idToClipEnd == 0 || idFromClipStart == 0){ 661 triggerLineScroll = true; 662 } 663 664 // A target id is specified (using 'changeWithId' method). No direction ('scrollWay = ""'). 665 // We check here the difference between target and previous Ids 666 if( checkIdRange ){ 667 if( idToClipEnd < 0 ){ 668 idToClipEnd = 0; 669 } 670 scrollWay = this.prevId < this.currId ? '-=' : '+='; 671 var idDiff = Math.abs( this.prevId - this.currId ); 672 673 // The nav will scroll if the target id is different from the previous Id 674 // The scroll value will then be equal to the 'jumpToId' var, overwriting the 'scroll' option value. 675 if( (idDiff-1 > idToClipEnd && scrollWay == '-=') || (idDiff > idFromClipStart && scrollWay == '+=') ){ 676 jumpToId = idDiff; 677 triggerLineScroll = true; 678 } 679 } 680 681 // Dertermine scroll direction 682 if(scrollWay == ""){ 683 if(this.prevId == this.currId && !currIdOnEdge){ 684 scrollWay = this.scrollWay == "-=" ? "+=" : "-="; 685 } 686 else{ 687 scrollWay = this.prevId < this.currId ? "-=" : "+="; 688 } 689 } 690 this.scrollWay = scrollWay; 691 } 692 693 // If line scrolling is required 694 if( triggerLineScroll ){ 695 696 // How many lines will scroll ? By default the answer is 'this.options.scroll' or 'jumpToId'. But we check if there are enough lines left. 697 var scrollPower = jumpToId > 0 ? jumpToId : this.options.scroll; 698 var LIremain = scrollWay == "-=" ? this.LIafter : this.LIbefore; 699 var scrollto = LIremain < scrollPower ? LIremain : scrollPower; 700 var scrollSize = scrollto * this.navLIsize; 701 702 // Once the nav has scrolled, the <li> tag matching the currId value may not be visible in the nav clip. So we calculate here a new currId regarding to the nav position. 703 this.newId = scrollWay == "-=" ? this.LIbefore+scrollto : this.LIbefore-scrollto+this.options.shownavitems-1; 704 if( (scrollWay == "-=" && this.newId > this.currId) || (scrollWay == "+=" && this.newId < this.currId) ){ 705 this.currId = this.newId; 706 } 707 708 // Circular option is active 709 if(this.options.circular){ 710 // Previous 711 if(this.LIbefore <= 0 && scrollWay == "+="){ 712 scrollWay = "-="; 713 this.currId = this.allItems-1; 714 scrollSize = ( this.LIafter/this.options.scroll )*( this.navLIsize*this.options.scroll ); 715 } 716 // Next 717 else if(this.LIafter == 0 && scrollWay == "-="){ 718 scrollWay = "+="; 719 this.currId = 0; 720 scrollSize = Math.abs(this.navPos); 721 } 722 } 723 724 // Finally, the scroll animation 725 this._animNav(scrollWay, scrollSize); 726 } 727 }; 728 729 this._animPanel = function( currId, scrollWay ) { 730 // Current panel elem 731 this.currPanel = this.panels.eq( currId ); 732 733 // Prev panel elem 734 this.prevPanelStill = this.panels.eq( this.prevId ); 735 736 var panelComplete = function(){ 737 if( $.isFunction(self.options.panelfxafter) ){ 738 self.options.panelfxafter(); 739 } 740 741 // Additional callbacks 742 self._runCallBacks( self.panelPostFns ); 743 }; 744 745 // Slide panel (only if not already active) 746 if( !this.currPanel.hasClass( this.cssNames.panelActive ) ){ 747 748 // First panel display (no effect) 749 if(this.firstTime){ 750 this.panelTransition = this.options.panelfxfirst; 751 var FirstTime = 1; 752 } 753 754 // Else we check for the transition effect 755 else{ 756 // No effect 757 var freeheightfx = this.options.freeheight && this.options.panelfx == "fading" ? "tabsfading" : "none"; 758 this.panelTransition = this.options.freeheight ? freeheightfx : this.options.panelfx; 759 } 760 761 // Call the before function is it exists 762 if( $.isFunction(self.options.panelfxbefore) ){ 763 self.options.panelfxbefore(); 764 } 765 766 // Additional callbacks 767 this._runCallBacks( this.panelAnteFns ); 768 769 // Call the transition function 770 this._panelTransitions[ this.panelTransition ]( scrollWay, FirstTime, panelComplete ); 771 } 772 }; 773 774 this._animNav = function( scrollWay, scrollSize ) { 775 var navComplete = function(){
776 // If the nav isn't circular, buttons are disabled when start or end is reached 777 if(!self.options.circular && self.scrollBtns){ 778 self.navBtns.removeClass(self.cssNames.btnDisable); 779 780 // Get the nav position 781 self._getNavPos(); 782 783 // Start is reached 784 if(self.LIbefore <= 0){ 785 self.navBtnPrev.addClass(self.cssNames.btnDisable); 786 } 787 // End is reached 788 else if(self.LIafter <= 0){ 789 self.navBtnNext.addClass(self.cssNames.btnDisable); 790 } 791 } 792 793 // Reload the animation if scrollcontinue option is true 794 if(self.scrollcontinue){ 795 setTimeout(function(){ self.scrollcontinue == "-=" ? self.navPrev() : self.navNext() }, 0); 796 } 797 798 // Nav callback 799 else if( $.isFunction(self.options.navfxafter) ){ 800 self.options.navfxafter(); 801 } 802 803 // Additional callbacks 804 self._runCallBacks( self.navPostFns ); 805 }; 806 807 // Call the before function is it exists 808 if( $.isFunction(self.options.navfxbefore) ){ 809 self.options.navfxbefore(); 810 } 811 812 // Additional callbacks 813 self._runCallBacks( self.navAnteFns ); 814 815 // Call transition 816 this._navTransitions[ this.options.navfx ](scrollWay, scrollSize, navComplete); 817 }; 818 819 this._runCallBacks = function( fns ){ 820 $.each( fns, function(index, item) { 821 if( $.isFunction( item ) ){ 822 item(); 823 } 824 }); 825 }; 826 827 this._clearCallBacks = function( fns ){ 828 fns.length = 0; 829 }; 830 831 this._panelTransitions = { 832 833 none: function(scrollWay, FirstTime, complete) { 834 self.panels.removeClass(self.cssNames.panelActive).hide(); 835 self.currPanel.addClass(self.cssNames.panelActive).show(); 836 complete(); 837 }, 838 839 sliding: function(scrollWay, FirstTime, complete) { 840 841 // Slide direction 842 if(scrollWay == ""){ 843 scrollWay = self.prevPanel < self.currId ? "-=" : "+="; 844 } 845 self.prevPanel = self.currId; 846 847 // Position/Size values for CSS 848 var cssPosValue = scrollWay == "-=" ? "+" : "-"; 849 var cssSlidePosAttr = self.options.verticalslide ? "top" : "left"; 850 var domObjSize = self.options.verticalnav ? self.domObjHeight : self.domObjWidth; 851 var slideScrollValue = cssSlidePosAttr == "top" ? {top: scrollWay+domObjSize} : {left: scrollWay+domObjSize}; 852 853 // Panels selection 854 self.oldPanel = $("."+self.cssNames.panelOld, self.domObj); 855 self.activePanel = $("."+self.cssNames.panelActive, self.domObj); 856 857 // Panels CSS properties 858 self.panels.css(cssSlidePosAttr, "0"); 859 self.oldPanel.removeClass(self.cssNames.panelOld).hide(); 860 self.activePanel.removeClass(self.cssNames.panelActive).addClass(self.cssNames.panelOld); 861 self.currPanel.addClass(self.cssNames.panelActive).css(cssSlidePosAttr, cssPosValue+domObjSize + "px").show(); 862 863 // Wrapper animation 864 self.panelsWrapper.stop(true, true).css(cssSlidePosAttr, "0").animate( 865 slideScrollValue, 866 self.options.panelfxspeed, 867 self.options.panelfxeasing, 868 function(){ 869 complete(); 870 } 871 ); 872 }, 873 874 fading: function(scrollWay, FirstTime, complete) { 875 if(FirstTime){ 876 self.panels.hide(); 877 } 878 else{ 879 self.currPanel.css("display","none"); 880 } 881 882 $("."+self.cssNames.panelOld, self.domObj).removeClass(self.cssNames.panelOld); 883 $("."+self.cssNames.panelActive, self.domObj).stop(true, true).removeClass(self.cssNames.panelActive).addClass(self.cssNames.panelOld); 884 885 self.currPanel.addClass(self.cssNames.panelActive) 886 .animate( 887 {"opacity":"show"}, 888 self.options.panelfxspeed, 889 self.options.panelfxeasing, 890 function(){ 891 complete(); 892 } 893 ); 894 }, 895 896 tabsfading: function(scrollWay, FirstTime, complete) { 897 self.panels.removeClass(self.cssNames.panelActive).hide(); 898 self.currPanel.fadeIn( 899 self.options.panelfxspeed, 900 function(){ 901 complete(); 902 } 903 ); 904 } 905 }; 906 907 this._navTransitions = { 908 909 none: function(scrollWay, scrollSize, complete) { 910 var newScrollSize = scrollWay == "-=" ? self.navPos-scrollSize : self.navPos+scrollSize; 911 self.navUL.css( self.cssPosAttr, newScrollSize +"px" ); 912 complete(); 913 }, 914 915 sliding: function(scrollWay, scrollSize, complete) { 916 self.navUL.animate( 917 self.cssPosAttr == "left" ? {left:scrollWay+scrollSize} : {top:scrollWay+scrollSize} 918 , self.options.scrollspeed, self.options.scrolleasing 919 , function(){ 920 complete(); 921 } 922 ); 923 } 924 }; 925 926 this.playBtnPause = function() { 927 this.playBtn.removeClass(this.cssNames.btnPause); 928 this.autoScrollStop(); 929 }; 930 931 this.playBtnStart = function() { 932 this.playBtn.addClass(self.cssNames.btnPause); 933 this.autoScrollStart(); 934 }; 935
936 this.autoScrollStart = function() { 937 var self = this; 938 this.isPlaying = setInterval(function(){ 939 self._change(null, "-=", null, self.lineScrollDo, null); 940 }, self.options.autospeed); 941 }; 942 943 this.autoScrollStop = function() { 944 clearTimeout(this.isPlaying); 945 this.isPlaying = null; 946 }; 947 948 this.changeWithId = function( id, eventSrc ) { 949 this._change(eventSrc, "", id, 0, 1); 950 }; 951 952 this.stepBackward = function(eventSrc) { 953 this._change(eventSrc, "+=", null, self.lineScrollDo, 1); 954 }; 955 956 this.stepForward = function(eventSrc) { 957 this._change(eventSrc, "-=", null, self.lineScrollDo, 1); 958 }; 959 960 this.navPrev = function(c) { 961 if(c){self.scrollcontinue = "-=";} 962 this._change(this.navBtnPrev, "+=", null, 1, 1); 963 }; 964 965 this.navNext = function(c) { 966 if(c){self.scrollcontinue = "+=";} 967 this._change(this.navBtnNext, "-=", null, 1, 1); 968 }; 969 970 this.navStopContinuous = function() { 971 self.scrollcontinue = ""; 972 }; 973 974 this.selectThumbnail = function( currId ){ 975 $("."+this.cssNames.selected, this.navUL).removeClass(this.cssNames.selected); 976 this.navLI.eq(currId).addClass(this.cssNames.selected); 977 }; 978 }; 979 980 // Launch plugin 981 $.fn.sliderkit = function( options ){ 982 983 return this.each(function(){ 984 985 $( this ).data( "sliderkit", new SliderKit()._init( this, options ) ); 986 987 }); 988 }; 989 990})(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.