Advertisement
Guest User

Untitled

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