1/*! 2 * jCarousel - Riding carousels with jQuery 3 * http://sorgalla.com/jcarousel/ 4 * 5 * Copyright (c) 2006 Jan Sorgalla (http://sorgalla.com) 6 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) 7 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses. 8 * 9 * Built on top of the jQuery library 10 * http://jquery.com 11 * 12 * Inspired by the "Carousel Component" by Bill Scott 13 * http://billwscott.com/carousel/ 14 */ 15 16(function($) { 17 /** 18 * Creates a carousel for all matched elements. 19 * 20 * @example $("#mycarousel").jcarousel(); 21 * @before <ul id="mycarousel" class="jcarousel-skin-name"><li>First item</li><li>Second item</li></ul> 22 * @result 23 * 24 * <div class="jcarousel-skin-name"> 25 * <div class="jcarousel-container"> 26 * <div class="jcarousel-clip"> 27 * <ul class="jcarousel-list"> 28 * <li class="jcarousel-item-1">First item</li> 29 * <li class="jcarousel-item-2">Second item</li> 30 * </ul> 31 * </div> 32 * <div disabled="disabled" class="jcarousel-prev jcarousel-prev-disabled"></div> 33 * <div class="jcarousel-next"></div> 34 * </div> 35 * </div> 36 * 37 * @method jcarousel 38 * @return jQuery 39 * @param o {Hash|String} A set of key/value pairs to set as configuration properties or a method name to call on a formerly created instance. 40 */ 41 $.fn.jcarousel = function(o) { 42 if (typeof o == 'string') { 43 var instance = $(this).data('jcarousel'), args = Array.prototype.slice.call(arguments, 1); 44 return instance[o].apply(instance, args); 45 } else 46 return this.each(function() { 47 $(this).data('jcarousel', new $jc(this, o)); 48 }); 49 }; 50 51 // Default configuration properties. 52 var defaults = { 53 vertical: false, 54 start: 1, 55 offset: 1, 56 size: null, 57 scroll: 3, 58 visible: null, 59 animation: 'normal', 60 easing: 'swing', 61 auto: 0, 62 wrap: null, 63 initCallback: null, 64 reloadCallback: null, 65 itemLoadCallback: null, 66 itemFirstInCallback: null, 67 itemFirstOutCallback: null, 68 itemLastInCallback: null, 69 itemLastOutCallback: null, 70 itemVisibleInCallback: null, 71 itemVisibleOutCallback: null, 72 buttonNextHTML: '<div></div>', 73 buttonPrevHTML: '<div></div>', 74 buttonNextEvent: 'click', 75 buttonPrevEvent: 'click', 76 buttonNextCallback: null, 77 buttonPrevCallback: null 78 }; 79 80 /** 81 * The jCarousel object. 82 * 83 * @constructor 84 * @class jcarousel 85 * @param e {HTMLElement} The element to create the carousel for. 86 * @param o {Object} A set of key/value pairs to set as configuration properties. 87 * @cat Plugins/jCarousel 88 */ 89 $.jcarousel = function(e, o) { 90 this.options = $.extend({}, defaults, o || {}); 91 92 this.locked = false; 93 94 this.container = null; 95 this.clip = null; 96 this.list = null; 97 this.buttonNext = null; 98 this.buttonPrev = null; 99 100 this.wh = !this.options.vertical ? 'width' : 'height'; 101 this.lt = !this.options.vertical ? 'left' : 'top'; 102 103 // Extract skin class 104 var skin = '', split = e.className.split(' '); 105 106 for (var i = 0; i < split.length; i++) { 107 if (split[i].indexOf('jcarousel-skin') != -1) { 108 $(e).removeClass(split[i]); 109 skin = split[i]; 110 break; 111 } 112 } 113 114 if (e.nodeName == 'UL' || e.nodeName == 'OL') { 115 this.list = $(e); 116 this.container = this.list.parent(); 117 118 if (this.container.hasClass('jcarousel-clip')) { 119 if (!this.container.parent().hasClass('jcarousel-container')) 120 this.container = this.container.wrap('<div></div>'); 121 122 this.container = this.container.parent(); 123 } else if (!this.container.hasClass('jcarousel-container')) 124 this.container = this.list.wrap('<div></div>').parent(); 125 } else { 126 this.container = $(e); 127 this.list = this.container.find('ul,ol').eq(0); 128 } 129 130 if (skin != '' && this.container.parent()[0].className.indexOf('jcarousel-skin') == -1) 131 this.container.wrap('<div class=" '+ skin + '"></div>'); 132 133 this.clip = this.list.parent(); 134
135 if (!this.clip.length || !this.clip.hasClass('jcarousel-clip')) 136 this.clip = this.list.wrap('<div></div>').parent(); 137 138 this.buttonNext = $('.jcarousel-next', this.container); 139 140 if (this.buttonNext.size() == 0 && this.options.buttonNextHTML != null) 141 this.buttonNext = this.clip.after(this.options.buttonNextHTML).next(); 142 143 this.buttonNext.addClass(this.className('jcarousel-next')); 144 145 this.buttonPrev = $('.jcarousel-prev', this.container); 146 147 if (this.buttonPrev.size() == 0 && this.options.buttonPrevHTML != null) 148 this.buttonPrev = this.clip.after(this.options.buttonPrevHTML).next(); 149 150 this.buttonPrev.addClass(this.className('jcarousel-prev')); 151 152 this.clip.addClass(this.className('jcarousel-clip')).css({ 153 overflow: 'hidden', 154 position: 'relative' 155 }); 156 this.list.addClass(this.className('jcarousel-list')).css({ 157 overflow: 'hidden', 158 position: 'relative', 159 top: 0, 160 left: 0, 161 margin: 0, 162 padding: 0 163 }); 164 this.container.addClass(this.className('jcarousel-container')).css({ 165 position: 'relative' 166 }); 167 168 var di = this.options.visible != null ? Math.ceil(this.clipping() / this.options.visible) : null; 169 var li = this.list.children('li'); 170 171 var self = this; 172 173 if (li.size() > 0) { 174 var wh = 0, i = this.options.offset; 175 li.each(function() { 176 self.format(this, i++); 177 wh += self.dimension(this, di); 178 }); 179 180 this.list.css(this.wh, wh + 'px'); 181 182 // Only set if not explicitly passed as option 183 if (!o || o.size === undefined) 184 this.options.size = li.size(); 185 } 186 187 // For whatever reason, .show() does not work in Safari... 188 this.container.css('display', 'block'); 189 this.buttonNext.css('display', 'block'); 190 this.buttonPrev.css('display', 'block'); 191 192 this.funcNext = function() { self.next(); }; 193 this.funcPrev = function() { self.prev(); }; 194 this.funcResize = function() { self.reload(); }; 195 196 if (this.options.initCallback != null) 197 this.options.initCallback(this, 'init'); 198 199 if ($.browser.safari) { 200 this.buttons(false, false); 201 $(window).bind('load.jcarousel', function() { self.setup(); }); 202 } else 203 this.setup(); 204 }; 205 206 // Create shortcut for internal use 207 var $jc = $.jcarousel; 208 209 $jc.fn = $jc.prototype = { 210 jcarousel: '0.2.4' 211 }; 212 213 $jc.fn.extend = $jc.extend = $.extend; 214 215 $jc.fn.extend({ 216 /** 217 * Setups the carousel. 218 * 219 * @method setup 220 * @return undefined 221 */ 222 setup: function() { 223 this.first = null; 224 this.last = null; 225 this.prevFirst = null; 226 this.prevLast = null; 227 this.animating = false; 228 this.timer = null; 229 this.tail = null; 230 this.inTail = false; 231 232 if (this.locked) 233 return; 234 235 this.list.css(this.lt, this.pos(this.options.offset) + 'px'); 236 var p = this.pos(this.options.start); 237 this.prevFirst = this.prevLast = null; 238 this.animate(p, false); 239 240 $(window).unbind('resize.jcarousel', this.funcResize).bind('resize.jcarousel', this.funcResize); 241 }, 242 243 /** 244 * Clears the list and resets the carousel. 245 * 246 * @method reset 247 * @return undefined 248 */ 249 reset: function() { 250 this.list.empty(); 251 252 this.list.css(this.lt, '0px'); 253 this.list.css(this.wh, '10px'); 254 255 if (this.options.initCallback != null) 256 this.options.initCallback(this, 'reset'); 257 258 this.setup(); 259 }, 260 261 /** 262 * Reloads the carousel and adjusts positions. 263 * 264 * @method reload 265 * @return undefined 266 */ 267 reload: function() { 268 if (this.tail != null && this.inTail) 269 this.list.css(this.lt, $jc.intval(this.list.css(this.lt)) + this.tail); 270 271 this.tail = null; 272 this.inTail = false;
273 274 if (this.options.reloadCallback != null) 275 this.options.reloadCallback(this); 276 277 if (this.options.visible != null) { 278 var self = this; 279 var di = Math.ceil(this.clipping() / this.options.visible), wh = 0, lt = 0; 280 $('li', this.list).each(function(i) { 281 wh += self.dimension(this, di); 282 if (i + 1 < self.first) 283 lt = wh; 284 }); 285 286 this.list.css(this.wh, wh + 'px'); 287 this.list.css(this.lt, -lt + 'px'); 288 } 289 290 this.scroll(this.first, false); 291 }, 292 293 /** 294 * Locks the carousel. 295 * 296 * @method lock 297 * @return undefined 298 */ 299 lock: function() { 300 this.locked = true; 301 this.buttons(); 302 }, 303 304 /** 305 * Unlocks the carousel. 306 * 307 * @method unlock 308 * @return undefined 309 */ 310 unlock: function() { 311 this.locked = false; 312 this.buttons(); 313 }, 314 315 /** 316 * Sets the size of the carousel. 317 * 318 * @method size 319 * @return undefined 320 * @param s {Number} The size of the carousel. 321 */ 322 size: function(s) { 323 if (s != undefined) { 324 this.options.size = s; 325 if (!this.locked) 326 this.buttons(); 327 } 328 329 return this.options.size; 330 }, 331 332 /** 333 * Checks whether a list element exists for the given index (or index range). 334 * 335 * @method get 336 * @return bool 337 * @param i {Number} The index of the (first) element. 338 * @param i2 {Number} The index of the last element. 339 */ 340 has: function(i, i2) { 341 if (i2 == undefined || !i2) 342 i2 = i; 343 344 if (this.options.size !== null && i2 > this.options.size) 345 i2 = this.options.size; 346 347 for (var j = i; j <= i2; j++) { 348 var e = this.get(j); 349 if (!e.length || e.hasClass('jcarousel-item-placeholder')) 350 return false; 351 } 352 353 return true; 354 }, 355 356 /** 357 * Returns a jQuery object with list element for the given index. 358 * 359 * @method get 360 * @return jQuery 361 * @param i {Number} The index of the element. 362 */ 363 get: function(i) { 364 return $('.jcarousel-item-' + i, this.list); 365 }, 366 367 /** 368 * Adds an element for the given index to the list. 369 * If the element already exists, it updates the inner html. 370 * Returns the created element as jQuery object. 371 * 372 * @method add 373 * @return jQuery 374 * @param i {Number} The index of the element. 375 * @param s {String} The innerHTML of the element. 376 */ 377 add: function(i, s) { 378 var e = this.get(i), old = 0, add = 0; 379 380 if (e.length == 0) { 381 var c, e = this.create(i), j = $jc.intval(i); 382 while (c = this.get(--j)) { 383 if (j <= 0 || c.length) { 384 j <= 0 ? this.list.prepend(e) : c.after(e); 385 break; 386 } 387 } 388 } else 389 old = this.dimension(e); 390 391 e.removeClass(this.className('jcarousel-item-placeholder')); 392 typeof s == 'string' ? e.html(s) : e.empty().append(s); 393 394 var di = this.options.visible != null ? Math.ceil(this.clipping() / this.options.visible) : null; 395 var wh = this.dimension(e, di) - old; 396 397 if (i > 0 && i < this.first) 398 this.list.css(this.lt, $jc.intval(this.list.css(this.lt)) - wh + 'px'); 399 400 this.list.css(this.wh, $jc.intval(this.list.css(this.wh)) + wh + 'px'); 401 402 return e; 403 }, 404 405 /** 406 * Removes an element for the given index from the list. 407 * 408 * @method remove 409 * @return undefined 410 * @param i {Number} The index of the element. 411 */ 412 remove: function(i) { 413 var e = this.get(i); 414 415 // Check if item exists and is not currently visible 416 if (!e.length || (i >= this.first && i <= this.last)) 417 return; 418 419 var d = this.dimension(e); 420 421 if (i < this.first) 422 this.list.css(this.lt, $jc.intval(this.list.css(this.lt)) + d + 'px'); 423 424 e.remove(); 425 426 this.list.css(this.wh, $jc.intval(this.list.css(this.wh)) - d + 'px'); 427 }, 428 429 /** 430 * Moves the carousel forwards. 431 * 432 * @method next 433 * @return undefined 434 */ 435 next: function() { 436 this.stopAuto(); 437 438 if (this.tail != null && !this.inTail) 439 this.scrollTail(false); 440 else 441 this.scroll(((this.options.wrap == 'both' || this.options.wrap == 'last') && this.options.size != null && this.last == this.options.size) ? 1 : this.first + this.options.scroll); 442 }, 443 444 /** 445 * Moves the carousel backwards. 446 * 447 * @method prev 448 * @return undefined 449 */ 450 prev: function() { 451 this.stopAuto(); 452 453 if (this.tail != null && this.inTail) 454 this.scrollTail(true); 455 else 456 this.scroll(((this.options.wrap == 'both' || this.options.wrap == 'first') && this.options.size != null && this.first == 1) ? this.options.size : this.first - this.options.scroll); 457 }, 458 459 /** 460 * Scrolls the tail of the carousel. 461 * 462 * @method scrollTail 463 * @return undefined 464 * @param b {Boolean} Whether scroll the tail back or forward. 465 */ 466 scrollTail: function(b) { 467 if (this.locked || this.animating || !this.tail) 468 return; 469 470 var pos = $jc.intval(this.list.css(this.lt)); 471 472 !b ? pos -= this.tail : pos += this.tail; 473 this.inTail = !b; 474 475 // Save for callbacks 476 this.prevFirst = this.first; 477 this.prevLast = this.last; 478 479 this.animate(pos); 480 }, 481 482 /** 483 * Scrolls the carousel to a certain position. 484 * 485 * @method scroll 486 * @return undefined 487 * @param i {Number} The index of the element to scoll to. 488 * @param a {Boolean} Flag indicating whether to perform animation. 489 */ 490 scroll: function(i, a) { 491 if (this.locked || this.animating) 492 return; 493 494 this.animate(this.pos(i), a); 495 }, 496 497 /** 498 * Prepares the carousel and return the position for a certian index. 499 * 500 * @method pos 501 * @return {Number} 502 * @param i {Number} The index of the element to scoll to. 503 */ 504 pos: function(i) { 505 var pos = $jc.intval(this.list.css(this.lt)); 506 507 if (this.locked || this.animating) 508 return pos; 509 510 if (this.options.wrap != 'circular') 511 i = i < 1 ? 1 : (this.options.size && i > this.options.size ? this.options.size : i); 512 513 var back = this.first > i; 514 515 // Create placeholders, new list width/height 516 // and new list position 517 var f = this.options.wrap != 'circular' && this.first <= 1 ? 1 : this.first; 518 var c = back ? this.get(f) : this.get(this.last); 519 var j = back ? f : f - 1; 520 var e = null, l = 0, p = false, d = 0, g; 521 522 while (back ? --j >= i : ++j < i) { 523 e = this.get(j); 524 p = !e.length; 525 if (e.length == 0) { 526 e = this.create(j).addClass(this.className('jcarousel-item-placeholder')); 527 c[back ? 'before' : 'after' ](e); 528 529 if (this.first != null && this.options.wrap == 'circular' && this.options.size !== null && (j <= 0 || j > this.options.size)) { 530 g = this.get(this.index(j)); 531 if (g.length) 532 this.add(j, g.children().clone(true)); 533 } 534 } 535 536 c = e; 537 d = this.dimension(e); 538 539 if (p) 540 l += d; 541 542 if (this.first != null && (this.options.wrap == 'circular' || (j >= 1 && (this.options.size == null || j <= this.options.size)))) 543 pos = back ? pos + d : pos - d; 544 } 545 546 // Calculate visible items 547 var clipping = this.clipping(); 548 var cache = []; 549 var visible = 0, j = i, v = 0; 550 var c = this.get(i - 1); 551 552 while (++visible) { 553 e = this.get(j); 554 p = !e.length; 555 if (e.length == 0) { 556 e = this.create(j).addClass(this.className('jcarousel-item-placeholder')); 557 // This should only happen on a next scroll 558 c.length == 0 ? this.list.prepend(e) : c[back ? 'before' : 'after' ](e); 559 560 if (this.first != null && this.options.wrap == 'circular' && this.options.size !== null && (j <= 0 || j > this.options.size)) { 561 g = this.get(this.index(j)); 562 if (g.length) 563 this.add(j, g.find('>*').clone(true)); 564 } 565 } 566 567 c = e; 568 var d = this.dimension(e); 569 if (d == 0) { 570 alert('jCarousel: No width/height set for items. This will cause an infinite loop. Aborting...'); 571 return 0; 572 } 573 574 if (this.options.wrap != 'circular' && this.options.size !== null && j > this.options.size) 575 cache.push(e); 576 else if (p) 577 l += d; 578 579 v += d; 580 581 if (v >= clipping) 582 break; 583 584 j++; 585 } 586 587 // Remove out-of-range placeholders 588 for (var x = 0; x < cache.length; x++) 589 cache[x].remove(); 590 591 // Resize list 592 if (l > 0) { 593 this.list.css(this.wh, this.dimension(this.list) + l + 'px'); 594 595 if (back) { 596 pos -= l; 597 this.list.css(this.lt, $jc.intval(this.list.css(this.lt)) - l + 'px'); 598 } 599 } 600 601 // Calculate first and last item 602 var last = i + visible - 1; 603 if (this.options.wrap != 'circular' && this.options.size && last > this.options.size) 604 last = this.options.size; 605 606 if (j > last) { 607 visible = 0, j = last, v = 0; 608 while (++visible) { 609 var e = this.get(j--); 610 if (!e.length) 611 break; 612 v += this.dimension(e); 613 if (v >= clipping) 614 break; 615 } 616 } 617 618 var first = last - visible + 1; 619 if (this.options.wrap != 'circular' && first < 1) 620 first = 1; 621 622 if (this.inTail && back) { 623 pos += this.tail; 624 this.inTail = false;
625 } 626 627 this.tail = null; 628 if (this.options.wrap != 'circular' && last == this.options.size && (last - visible + 1) >= 1) { 629 var m = $jc.margin(this.get(last), !this.options.vertical ? 'marginRight' : 'marginBottom'); 630 if ((v - m) > clipping) 631 this.tail = v - clipping - m; 632 } 633 634 // Adjust position 635 while (i-- > first) 636 pos += this.dimension(this.get(i)); 637 638 // Save visible item range 639 this.prevFirst = this.first; 640 this.prevLast = this.last; 641 this.first = first; 642 this.last = last; 643 644 return pos; 645 }, 646 647 /** 648 * Animates the carousel to a certain position. 649 * 650 * @method animate 651 * @return undefined 652 * @param p {Number} Position to scroll to. 653 * @param a {Boolean} Flag indicating whether to perform animation. 654 */ 655 animate: function(p, a) { 656 if (this.locked || this.animating) 657 return; 658 659 this.animating = true; 660 661 var self = this; 662 var scrolled = function() { 663 self.animating = false; 664 665 if (p == 0) 666 self.list.css(self.lt, 0); 667 668 if (self.options.wrap == 'circular' || self.options.wrap == 'both' || self.options.wrap == 'last' || self.options.size == null || self.last < self.options.size) 669 self.startAuto(); 670 671 self.buttons(); 672 self.notify('onAfterAnimation'); 673 }; 674 675 this.notify('onBeforeAnimation'); 676 677 // Animate 678 if (!this.options.animation || a == false) { 679 this.list.css(this.lt, p + 'px'); 680 scrolled(); 681 } else { 682 var o = !this.options.vertical ? {'left': p} : {'top': p}; 683 this.list.animate(o, this.options.animation, this.options.easing, scrolled); 684 } 685 }, 686 687 /** 688 * Starts autoscrolling. 689 * 690 * @method auto 691 * @return undefined 692 * @param s {Number} Seconds to periodically autoscroll the content. 693 */ 694 startAuto: function(s) { 695 if (s != undefined) 696 this.options.auto = s; 697 698 if (this.options.auto == 0) 699 return this.stopAuto(); 700 701 if (this.timer != null) 702 return; 703 704 var self = this; 705 this.timer = setTimeout(function() { self.next(); }, this.options.auto * 1000); 706 }, 707 708 /** 709 * Stops autoscrolling. 710 * 711 * @method stopAuto 712 * @return undefined 713 */ 714 stopAuto: function() { 715 if (this.timer == null) 716 return; 717 718 clearTimeout(this.timer); 719 this.timer = null; 720 }, 721 722 /** 723 * Sets the states of the prev/next buttons. 724 * 725 * @method buttons 726 * @return undefined 727 */ 728 buttons: function(n, p) { 729 if (n == undefined || n == null) { 730 var n = !this.locked && this.options.size !== 0 && ((this.options.wrap && this.options.wrap != 'first') || this.options.size == null || this.last < this.options.size); 731 if (!this.locked && (!this.options.wrap || this.options.wrap == 'first') && this.options.size != null && this.last >= this.options.size) 732 n = this.tail != null && !this.inTail; 733 } 734 735 if (p == undefined || p == null) { 736 var p = !this.locked && this.options.size !== 0 && ((this.options.wrap && this.options.wrap != 'last') || this.first > 1); 737 if (!this.locked && (!this.options.wrap || this.options.wrap == 'last') && this.options.size != null && this.first == 1) 738 p = this.tail != null && this.inTail; 739 } 740 741 var self = this; 742 743 this.buttonNext[n ? 'bind' : 'unbind'](this.options.buttonNextEvent + '.jcarousel', this.funcNext)[n ? 'removeClass' : 'addClass'](this.className('jcarousel-next-disabled')).attr('disabled', n ? false : true); 744 this.buttonPrev[p ? 'bind' : 'unbind'](this.options.buttonPrevEvent + '.jcarousel', this.funcPrev)[p ? 'removeClass' : 'addClass'](this.className('jcarousel-prev-disabled')).attr('disabled', p ? false : true); 745 746 if (this.buttonNext.length >
746 0 && (this.buttonNext[0].jcarouselstate == undefined || this.buttonNext[0].jcarouselstate != n) && this.options.buttonNextCallback != null) { 747 this.buttonNext.each(function() { self.options.buttonNextCallback(self, this, n); }); 748 this.buttonNext[0].jcarouselstate = n; 749 } 750 751 if (this.buttonPrev.length > 0 && (this.buttonPrev[0].jcarouselstate == undefined || this.buttonPrev[0].jcarouselstate != p) && this.options.buttonPrevCallback != null) { 752 this.buttonPrev.each(function() { self.options.buttonPrevCallback(self, this, p); }); 753 this.buttonPrev[0].jcarouselstate = p; 754 } 755 }, 756 757 /** 758 * Notify callback of a specified event. 759 * 760 * @method notify 761 * @return undefined 762 * @param evt {String} The event name 763 */ 764 notify: function(evt) { 765 var state = this.prevFirst == null ? 'init' : (this.prevFirst < this.first ? 'next' : 'prev'); 766 767 // Load items 768 this.callback('itemLoadCallback', evt, state); 769 770 if (this.prevFirst !== this.first) { 771 this.callback('itemFirstInCallback', evt, state, this.first); 772 this.callback('itemFirstOutCallback', evt, state, this.prevFirst); 773 } 774 775 if (this.prevLast !== this.last) { 776 this.callback('itemLastInCallback', evt, state, this.last); 777 this.callback('itemLastOutCallback', evt, state, this.prevLast); 778 } 779 780 this.callback('itemVisibleInCallback', evt, state, this.first, this.last, this.prevFirst, this.prevLast); 781 this.callback('itemVisibleOutCallback', evt, state, this.prevFirst, this.prevLast, this.first, this.last); 782 }, 783 784 callback: function(cb, evt, state, i1, i2, i3, i4) { 785 if (this.options[cb] == undefined || (typeof this.options[cb] != 'object' && evt != 'onAfterAnimation')) 786 return; 787 788 var callback = typeof this.options[cb] == 'object' ? this.options[cb][evt] : this.options[cb]; 789 790 if (!$.isFunction(callback)) 791 return; 792 793 var self = this; 794 795 if (i1 === undefined) 796 callback(self, state, evt); 797 else if (i2 === undefined) 798 this.get(i1).each(function() { callback(self, this, i1, state, evt); }); 799 else { 800 for (var i = i1; i <= i2; i++) 801 if (i !== null && !(i >= i3 && i <= i4)) 802 this.get(i).each(function() { callback(self, this, i, state, evt); }); 803 } 804 }, 805 806 create: function(i) { 807 return this.format('<li></li>', i); 808 }, 809 810 format: function(e, i) { 811 var $e = $(e).addClass(this.className('jcarousel-item')).addClass(this.className('jcarousel-item-' + i)).css({ 812 'float': 'left', 813 'list-style': 'none' 814 }); 815 $e.attr('jcarouselindex', i); 816 return $e; 817 }, 818 819 className: function(c) { 820 return c + ' ' + c + (!this.options.vertical ? '-horizontal' : '-vertical'); 821 }, 822 823 dimension: function(e, d) { 824 var el = e.jquery != undefined ? e[0] : e; 825 826 var old = !this.options.vertical ? 827 el.offsetWidth + $jc.margin(el, 'marginLeft') + $jc.margin(el, 'marginRight') : 828 el.offsetHeight + $jc.margin(el, 'marginTop') + $jc.margin(el, 'marginBottom'); 829 830 if (d == undefined || old == d) 831 return old; 832 833 var w = !this.options.vertical ? 834 d - $jc.margin(el, 'marginLeft') - $jc.margin(el, 'marginRight') : 835 d - $jc.margin(el, 'marginTop') - $jc.margin(el, 'marginBottom'); 836 837 $(el).css(this.wh, w + 'px'); 838 839 return this.dimension(el); 840 }, 841 842 clipping: function() { 843 return !this.options.vertical ? 844 this.clip[0].offsetWidth - $jc.intval(this.clip.css('borderLeftWidth')) - $jc.intval(this.clip.css('borderRightWidth')) : 845 this.clip[0].offsetHeight - $jc.intval(this.clip.css('borderTopWidth')) - $jc.intval(this.clip.css('borderBottomWidth')); 846 }, 847 848 index: function(i, s) { 849 if (s == undefined) 850 s = this.options.size; 851 852 return Math.round((((i-1) / s) - Math.floor((i-1) / s)) * s) + 1; 853 } 854 }); 855 856 $jc.extend({ 857 /** 858 * Gets/Sets the global default configuration properties. 859 * 860 * @method defaults 861 * @return {Object} 862 * @param d {Object} A set of key/value pairs to set as configuration properties. 863 */ 864 defaults: function(d) { 865 return $.extend(defaults, d || {}); 866 }, 867 868 margin: function(e, p) { 869 if (!e) 870 return 0; 871 872 var el = e.jquery != undefined ? e[0] : e; 873 874 if (p == 'marginRight' && $.browser.safari) { 875 var old = {'display': 'block', 'float': 'none', 'width': 'auto'}, oWidth, oWidth2; 876 877 $.swap(el, old, function() { oWidth = el.offsetWidth; }); 878 879 old['marginRight'] = 0; 880 $.swap(el, old, function() { oWidth2 = el.offsetWidth; }); 881 882 return oWidth2 - oWidth; 883 } 884 885 return $jc.intval($.css(el, p)); 886 }, 887 888 intval: function(v) { 889 v = parseInt(v); 890 return isNaN(v) ? 0 : v; 891 } 892 }); 893 894})(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.