jquery.bxSlider.js 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260
  1. /**
  2. * jQuery bxSlider v3.0
  3. * http://bxslider.com
  4. *
  5. * Copyright 2011, Steven Wanderski
  6. * http://bxcreative.com
  7. *
  8. * Free to use and abuse under the MIT license.
  9. * http://www.opensource.org/licenses/mit-license.php
  10. *
  11. */
  12. (function($){
  13. $.fn.bxSlider = function(options){
  14. var defaults = {
  15. mode: 'horizontal', // 'horizontal', 'vertical', 'fade'
  16. infiniteLoop: true, // true, false - display first slide after last
  17. hideControlOnEnd: false, // true, false - if true, will hide 'next' control on last slide and 'prev' control on first
  18. controls: true, // true, false - previous and next controls
  19. speed: 500, // integer - in ms, duration of time slide transitions will occupy
  20. easing: 'swing', // used with jquery.easing.1.3.js - see http://gsgd.co.uk/sandbox/jquery/easing/ for available options
  21. pager: false, // true / false - display a pager
  22. pagerSelector: null, // jQuery selector - element to contain the pager. ex: '#pager'
  23. pagerType: 'full', // 'full', 'short' - if 'full' pager displays 1,2,3... if 'short' pager displays 1 / 4
  24. pagerLocation: 'bottom', // 'bottom', 'top' - location of pager
  25. pagerShortSeparator: '/', // string - ex: 'of' pager would display 1 of 4
  26. pagerActiveClass: 'pager-active', // string - classname attached to the active pager link
  27. nextText: 'next', // string - text displayed for 'next' control
  28. nextImage: '', // string - filepath of image used for 'next' control. ex: 'images/next.jpg'
  29. nextSelector: null, // jQuery selector - element to contain the next control. ex: '#next'
  30. prevText: 'prev', // string - text displayed for 'previous' control
  31. prevImage: '', // string - filepath of image used for 'previous' control. ex: 'images/prev.jpg'
  32. prevSelector: null, // jQuery selector - element to contain the previous control. ex: '#next'
  33. captions: false, // true, false - display image captions (reads the image 'title' tag)
  34. captionsSelector: null, // jQuery selector - element to contain the captions. ex: '#captions'
  35. auto: false, // true, false - make slideshow change automatically
  36. autoDirection: 'next', // 'next', 'prev' - direction in which auto show will traverse
  37. autoControls: false, // true, false - show 'start' and 'stop' controls for auto show
  38. autoControlsSelector: null, // jQuery selector - element to contain the auto controls. ex: '#auto-controls'
  39. autoStart: true, // true, false - if false show will wait for 'start' control to activate
  40. autoHover: false, // true, false - if true show will pause on mouseover
  41. autoDelay: 0, // integer - in ms, the amount of time before starting the auto show
  42. pause: 3000, // integer - in ms, the duration between each slide transition
  43. startText: 'start', // string - text displayed for 'start' control
  44. startImage: '', // string - filepath of image used for 'start' control. ex: 'images/start.jpg'
  45. stopText: 'stop', // string - text displayed for 'stop' control
  46. stopImage: '', // string - filepath of image used for 'stop' control. ex: 'images/stop.jpg'
  47. ticker: false, // true, false - continuous motion ticker mode (think news ticker)
  48. // note: autoControls, autoControlsSelector, and autoHover apply to ticker!
  49. tickerSpeed: 5000, // float - use value between 1 and 5000 to determine ticker speed - the smaller the value the faster the ticker speed
  50. tickerDirection: 'next', // 'next', 'prev' - direction in which ticker show will traverse
  51. tickerHover: false, // true, false - if true ticker will pause on mouseover
  52. wrapperClass: 'bx-wrapper', // string - classname attached to the slider wraper
  53. startingSlide: 0, // integer - show will start on specified slide. note: slides are zero based!
  54. displaySlideQty: 1, // integer - number of slides to display at once
  55. moveSlideQty: 1, // integer - number of slides to move at once
  56. randomStart: false, // true, false - if true show will start on a random slide
  57. onBeforeSlide: function(){}, // function(currentSlideNumber, totalSlideQty, currentSlideHtmlObject) - advanced use only! see the tutorial here: http://bxslider.com/custom-pager
  58. onAfterSlide: function(){}, // function(currentSlideNumber, totalSlideQty, currentSlideHtmlObject) - advanced use only! see the tutorial here: http://bxslider.com/custom-pager
  59. onLastSlide: function(){}, // function(currentSlideNumber, totalSlideQty, currentSlideHtmlObject) - advanced use only! see the tutorial here: http://bxslider.com/custom-pager
  60. onFirstSlide: function(){}, // function(currentSlideNumber, totalSlideQty, currentSlideHtmlObject) - advanced use only! see the tutorial here: http://bxslider.com/custom-pager
  61. onNextSlide: function(){}, // function(currentSlideNumber, totalSlideQty, currentSlideHtmlObject) - advanced use only! see the tutorial here: http://bxslider.com/custom-pager
  62. onPrevSlide: function(){}, // function(currentSlideNumber, totalSlideQty, currentSlideHtmlObject) - advanced use only! see the tutorial here: http://bxslider.com/custom-pager
  63. buildPager: null // function(slideIndex, slideHtmlObject){ return string; } - advanced use only! see the tutorial here: http://bxslider.com/custom-pager
  64. }
  65. var options = $.extend(defaults, options);
  66. // cache the base element
  67. var base = this;
  68. // initialize (and localize) all variables
  69. var $parent = '';
  70. var $origElement = '';
  71. var $children = '';
  72. var $outerWrapper = '';
  73. var $firstChild = '';
  74. var childrenWidth = '';
  75. var childrenOuterWidth = '';
  76. var wrapperWidth = '';
  77. var wrapperHeight = '';
  78. var $pager = '';
  79. var interval = '';
  80. var $autoControls = '';
  81. var $stopHtml = '';
  82. var $startContent = '';
  83. var $stopContent = '';
  84. var autoPlaying = true;
  85. var loaded = false;
  86. var childrenMaxWidth = 0;
  87. var childrenMaxHeight = 0;
  88. var currentSlide = 0;
  89. var origLeft = 0;
  90. var origTop = 0;
  91. var origShowWidth = 0;
  92. var origShowHeight = 0;
  93. var tickerLeft = 0;
  94. var tickerTop = 0;
  95. var isWorking = false;
  96. var firstSlide = 0;
  97. var lastSlide = $children.length - 1;
  98. // PUBLIC FUNCTIONS
  99. /**
  100. * Go to specified slide
  101. */
  102. this.goToSlide = function(number, stopAuto){
  103. if(!isWorking){
  104. isWorking = true;
  105. // set current slide to argument
  106. currentSlide = number;
  107. options.onBeforeSlide(currentSlide, $children.length, $children.eq(currentSlide));
  108. // check if stopAuto argument is supplied
  109. if(typeof(stopAuto) == 'undefined'){
  110. var stopAuto = true;
  111. }
  112. if(stopAuto){
  113. // if show is auto playing, stop it
  114. if(options.auto){
  115. base.stopShow(true);
  116. }
  117. }
  118. slide = number;
  119. // check for first slide callback
  120. if(slide == firstSlide){
  121. options.onFirstSlide(currentSlide, $children.length, $children.eq(currentSlide));
  122. }
  123. // check for last slide callback
  124. if(slide == lastSlide){
  125. options.onLastSlide(currentSlide, $children.length, $children.eq(currentSlide));
  126. }
  127. // horizontal
  128. if(options.mode == 'horizontal'){
  129. $parent.animate({'left': '-'+getSlidePosition(slide, 'left')+'px'}, options.speed, options.easing, function(){
  130. isWorking = false;
  131. // perform the callback function
  132. options.onAfterSlide(currentSlide, $children.length, $children.eq(currentSlide));
  133. });
  134. // vertical
  135. }else if(options.mode == 'vertical'){
  136. $parent.animate({'top': '-'+getSlidePosition(slide, 'top')+'px'}, options.speed, options.easing, function(){
  137. isWorking = false;
  138. // perform the callback function
  139. options.onAfterSlide(currentSlide, $children.length, $children.eq(currentSlide));
  140. });
  141. // fade
  142. }else if(options.mode == 'fade'){
  143. setChildrenFade();
  144. }
  145. // check to remove controls on last/first slide
  146. checkEndControls();
  147. // accomodate multi slides
  148. if(options.moveSlideQty > 1){
  149. number = Math.floor(number / options.moveSlideQty);
  150. }
  151. // make the current slide active
  152. makeSlideActive(number);
  153. // display the caption
  154. showCaptions();
  155. }
  156. }
  157. /**
  158. * Go to next slide
  159. */
  160. this.goToNextSlide = function(stopAuto){
  161. // check if stopAuto argument is supplied
  162. if(typeof(stopAuto) == 'undefined'){
  163. var stopAuto = true;
  164. }
  165. if(stopAuto){
  166. // if show is auto playing, stop it
  167. if(options.auto){
  168. base.stopShow(true);
  169. }
  170. }
  171. // makes slideshow finite
  172. if(!options.infiniteLoop){
  173. if(!isWorking){
  174. var slideLoop = false;
  175. // make current slide the old value plus moveSlideQty
  176. currentSlide = (currentSlide + (options.moveSlideQty));
  177. // if current slide has looped on itself
  178. if(currentSlide <= lastSlide){
  179. checkEndControls();
  180. // next slide callback
  181. options.onNextSlide(currentSlide, $children.length, $children.eq(currentSlide));
  182. // move to appropriate slide
  183. base.goToSlide(currentSlide);
  184. }else{
  185. currentSlide -= options.moveSlideQty;
  186. }
  187. } // end if(!isWorking)
  188. }else{
  189. if(!isWorking){
  190. isWorking = true;
  191. var slideLoop = false;
  192. // make current slide the old value plus moveSlideQty
  193. currentSlide = (currentSlide + options.moveSlideQty);
  194. // if current slide has looped on itself
  195. if(currentSlide > lastSlide){
  196. currentSlide = currentSlide % $children.length;
  197. slideLoop = true;
  198. }
  199. // next slide callback
  200. options.onNextSlide(currentSlide, $children.length, $children.eq(currentSlide));
  201. // slide before callback
  202. options.onBeforeSlide(currentSlide, $children.length, $children.eq(currentSlide));
  203. if(options.mode == 'horizontal'){
  204. // get the new 'left' property for $parent
  205. var parentLeft = (options.moveSlideQty * childrenOuterWidth);
  206. // animate to the new 'left'
  207. $parent.animate({'left': '-='+parentLeft+'px'}, options.speed, options.easing, function(){
  208. isWorking = false;
  209. // if its time to loop, reset the $parent
  210. if(slideLoop){
  211. $parent.css('left', '-'+getSlidePosition(currentSlide, 'left')+'px');
  212. }
  213. // perform the callback function
  214. options.onAfterSlide(currentSlide, $children.length, $children.eq(currentSlide));
  215. });
  216. }else if(options.mode == 'vertical'){
  217. // get the new 'left' property for $parent
  218. var parentTop = (options.moveSlideQty * childrenMaxHeight);
  219. // animate to the new 'left'
  220. $parent.animate({'top': '-='+parentTop+'px'}, options.speed, options.easing, function(){
  221. isWorking = false;
  222. // if its time to loop, reset the $parent
  223. if(slideLoop){
  224. $parent.css('top', '-'+getSlidePosition(currentSlide, 'top')+'px');
  225. }
  226. // perform the callback function
  227. options.onAfterSlide(currentSlide, $children.length, $children.eq(currentSlide));
  228. });
  229. }else if(options.mode == 'fade'){
  230. setChildrenFade();
  231. }
  232. // make the current slide active
  233. if(options.moveSlideQty > 1){
  234. makeSlideActive(Math.ceil(currentSlide / options.moveSlideQty));
  235. }else{
  236. makeSlideActive(currentSlide);
  237. }
  238. // display the caption
  239. showCaptions();
  240. } // end if(!isWorking)
  241. }
  242. } // end function
  243. /**
  244. * Go to previous slide
  245. */
  246. this.goToPreviousSlide = function(stopAuto){
  247. // check if stopAuto argument is supplied
  248. if(typeof(stopAuto) == 'undefined'){
  249. var stopAuto = true;
  250. }
  251. if(stopAuto){
  252. // if show is auto playing, stop it
  253. if(options.auto){
  254. base.stopShow(true);
  255. }
  256. }
  257. // makes slideshow finite
  258. if(!options.infiniteLoop){
  259. if(!isWorking){
  260. var slideLoop = false;
  261. // make current slide the old value plus moveSlideQty
  262. currentSlide = currentSlide - options.moveSlideQty;
  263. // if current slide has looped on itself
  264. if(currentSlide < 0){
  265. currentSlide = 0;
  266. // if specified, hide the control on the last slide
  267. if(options.hideControlOnEnd){
  268. $('.bx-prev', $outerWrapper).hide();
  269. }
  270. }
  271. checkEndControls();
  272. // next slide callback
  273. options.onPrevSlide(currentSlide, $children.length, $children.eq(currentSlide));
  274. // move to appropriate slide
  275. base.goToSlide(currentSlide);
  276. }
  277. }else{
  278. if(!isWorking){
  279. isWorking = true;
  280. var slideLoop = false;
  281. // make current slide the old value plus moveSlideQty
  282. currentSlide = (currentSlide - (options.moveSlideQty));
  283. // if current slide has looped on itself
  284. if(currentSlide < 0){
  285. negativeOffset = (currentSlide % $children.length);
  286. if(negativeOffset == 0){
  287. currentSlide = 0;
  288. }else{
  289. currentSlide = ($children.length) + negativeOffset;
  290. }
  291. slideLoop = true;
  292. }
  293. // next slide callback
  294. options.onPrevSlide(currentSlide, $children.length, $children.eq(currentSlide));
  295. // slide before callback
  296. options.onBeforeSlide(currentSlide, $children.length, $children.eq(currentSlide));
  297. if(options.mode == 'horizontal'){
  298. // get the new 'left' property for $parent
  299. var parentLeft = (options.moveSlideQty * childrenOuterWidth);
  300. // animate to the new 'left'
  301. $parent.animate({'left': '+='+parentLeft+'px'}, options.speed, options.easing, function(){
  302. isWorking = false;
  303. // if its time to loop, reset the $parent
  304. if(slideLoop){
  305. $parent.css('left', '-'+getSlidePosition(currentSlide, 'left')+'px');
  306. }
  307. // perform the callback function
  308. options.onAfterSlide(currentSlide, $children.length, $children.eq(currentSlide));
  309. });
  310. }else if(options.mode == 'vertical'){
  311. // get the new 'left' property for $parent
  312. var parentTop = (options.moveSlideQty * childrenMaxHeight);
  313. // animate to the new 'left'
  314. $parent.animate({'top': '+='+parentTop+'px'}, options.speed, options.easing, function(){
  315. isWorking = false;
  316. // if its time to loop, reset the $parent
  317. if(slideLoop){
  318. $parent.css('top', '-'+getSlidePosition(currentSlide, 'top')+'px');
  319. }
  320. // perform the callback function
  321. options.onAfterSlide(currentSlide, $children.length, $children.eq(currentSlide));
  322. });
  323. }else if(options.mode == 'fade'){
  324. setChildrenFade();
  325. }
  326. // make the current slide active
  327. if(options.moveSlideQty > 1){
  328. makeSlideActive(Math.ceil(currentSlide / options.moveSlideQty));
  329. }else{
  330. makeSlideActive(currentSlide);
  331. }
  332. // display the caption
  333. showCaptions();
  334. } // end if(!isWorking)
  335. }
  336. } // end function
  337. /**
  338. * Go to first slide
  339. */
  340. this.goToFirstSlide = function(stopAuto){
  341. // check if stopAuto argument is supplied
  342. if(typeof(stopAuto) == 'undefined'){
  343. var stopAuto = true;
  344. }
  345. base.goToSlide(firstSlide, stopAuto);
  346. }
  347. /**
  348. * Go to last slide
  349. */
  350. this.goToLastSlide = function(){
  351. // check if stopAuto argument is supplied
  352. if(typeof(stopAuto) == 'undefined'){
  353. var stopAuto = true;
  354. }
  355. base.goToSlide(lastSlide, stopAuto);
  356. }
  357. /**
  358. * Get the current slide
  359. */
  360. this.getCurrentSlide = function(){
  361. return currentSlide;
  362. }
  363. /**
  364. * Get the total slide count
  365. */
  366. this.getSlideCount = function(){
  367. return $children.length;
  368. }
  369. /**
  370. * Stop the slideshow
  371. */
  372. this.stopShow = function(changeText){
  373. clearInterval(interval);
  374. // check if changeText argument is supplied
  375. if(typeof(changeText) == 'undefined'){
  376. var changeText = true;
  377. }
  378. if(changeText && options.autoControls){
  379. $autoControls.html($startContent).removeClass('stop').addClass('start');
  380. autoPlaying = false;
  381. }
  382. }
  383. /**
  384. * Start the slideshow
  385. */
  386. this.startShow = function(changeText){
  387. // check if changeText argument is supplied
  388. if(typeof(changeText) == 'undefined'){
  389. var changeText = true;
  390. }
  391. setAutoInterval();
  392. if(changeText && options.autoControls){
  393. $autoControls.html($stopContent).removeClass('start').addClass('stop');
  394. autoPlaying = true;
  395. }
  396. }
  397. /**
  398. * Stops the ticker
  399. */
  400. this.stopTicker = function(changeText){
  401. $parent.stop();
  402. // check if changeText argument is supplied
  403. if(typeof(changeText) == 'undefined'){
  404. var changeText = true;
  405. }
  406. if(changeText && options.ticker){
  407. $autoControls.html($startContent).removeClass('stop').addClass('start');
  408. autoPlaying = false;
  409. }
  410. }
  411. /**
  412. * Starts the ticker
  413. */
  414. this.startTicker = function(changeText){
  415. if(options.mode == 'horizontal'){
  416. if(options.tickerDirection == 'next'){
  417. // get the 'left' property where the ticker stopped
  418. var stoppedLeft = parseInt($parent.css('left'));
  419. // calculate the remaining distance the show must travel until the loop
  420. var remainingDistance = (origShowWidth + stoppedLeft) + $children.eq(0).width();
  421. }else if(options.tickerDirection == 'prev'){
  422. // get the 'left' property where the ticker stopped
  423. var stoppedLeft = -parseInt($parent.css('left'));
  424. // calculate the remaining distance the show must travel until the loop
  425. var remainingDistance = (stoppedLeft) - $children.eq(0).width();
  426. }
  427. // calculate the speed ratio to seamlessly finish the loop
  428. var finishingSpeed = (remainingDistance * options.tickerSpeed) / origShowWidth;
  429. // call the show
  430. moveTheShow(tickerLeft, remainingDistance, finishingSpeed);
  431. }else if(options.mode == 'vertical'){
  432. if(options.tickerDirection == 'next'){
  433. // get the 'top' property where the ticker stopped
  434. var stoppedTop = parseInt($parent.css('top'));
  435. // calculate the remaining distance the show must travel until the loop
  436. var remainingDistance = (origShowHeight + stoppedTop) + $children.eq(0).height();
  437. }else if(options.tickerDirection == 'prev'){
  438. // get the 'left' property where the ticker stopped
  439. var stoppedTop = -parseInt($parent.css('top'));
  440. // calculate the remaining distance the show must travel until the loop
  441. var remainingDistance = (stoppedTop) - $children.eq(0).height();
  442. }
  443. // calculate the speed ratio to seamlessly finish the loop
  444. var finishingSpeed = (remainingDistance * options.tickerSpeed) / origShowHeight;
  445. // call the show
  446. moveTheShow(tickerTop, remainingDistance, finishingSpeed);
  447. // check if changeText argument is supplied
  448. if(typeof(changeText) == 'undefined'){
  449. var changeText = true;
  450. }
  451. if(changeText && options.ticker){
  452. $autoControls.html($stopContent).removeClass('start').addClass('stop');
  453. autoPlaying = true;
  454. }
  455. }
  456. }
  457. /**
  458. * Initialize a new slideshow
  459. */
  460. this.initShow = function(){
  461. // reinitialize all variables
  462. // base = this;
  463. $parent = $(this);
  464. $origElement = $parent.clone();
  465. $children = $parent.children();
  466. $outerWrapper = '';
  467. $firstChild = $parent.children(':first');
  468. childrenWidth = $firstChild.width();
  469. childrenMaxWidth = 0;
  470. childrenOuterWidth = $firstChild.outerWidth();
  471. childrenMaxHeight = 0;
  472. wrapperWidth = getWrapperWidth();
  473. wrapperHeight = getWrapperHeight();
  474. isWorking = false;
  475. $pager = '';
  476. currentSlide = 0;
  477. origLeft = 0;
  478. origTop = 0;
  479. interval = '';
  480. $autoControls = '';
  481. $stopHtml = '';
  482. $startContent = '';
  483. $stopContent = '';
  484. autoPlaying = true;
  485. loaded = false;
  486. origShowWidth = 0;
  487. origShowHeight = 0;
  488. tickerLeft = 0;
  489. tickerTop = 0;
  490. firstSlide = 0;
  491. lastSlide = $children.length - 1;
  492. // get the largest child's height and width
  493. $children.each(function(index) {
  494. if($(this).outerHeight() > childrenMaxHeight){
  495. childrenMaxHeight = $(this).outerHeight();
  496. }
  497. if($(this).outerWidth() > childrenMaxWidth){
  498. childrenMaxWidth = $(this).outerWidth();
  499. }
  500. });
  501. // get random slide number
  502. if(options.randomStart){
  503. var randomNumber = Math.floor(Math.random() * $children.length);
  504. currentSlide = randomNumber;
  505. origLeft = childrenOuterWidth * (options.moveSlideQty + randomNumber);
  506. origTop = childrenMaxHeight * (options.moveSlideQty + randomNumber);
  507. // start show at specific slide
  508. }else{
  509. currentSlide = options.startingSlide;
  510. origLeft = childrenOuterWidth * (options.moveSlideQty + options.startingSlide);
  511. origTop = childrenMaxHeight * (options.moveSlideQty + options.startingSlide);
  512. }
  513. // set initial css
  514. initCss();
  515. // check to show pager
  516. if(options.pager && !options.ticker){
  517. if(options.pagerType == 'full'){
  518. showPager('full');
  519. }else if(options.pagerType == 'short'){
  520. showPager('short');
  521. }
  522. }
  523. // check to show controls
  524. if(options.controls && !options.ticker){
  525. setControlsVars();
  526. }
  527. // check if auto
  528. if(options.auto || options.ticker){
  529. // check if auto controls are displayed
  530. if(options.autoControls){
  531. setAutoControlsVars();
  532. }
  533. // check if show should auto start
  534. if(options.autoStart){
  535. // check if autostart should delay
  536. setTimeout(function(){
  537. base.startShow(true);
  538. }, options.autoDelay);
  539. }else{
  540. base.stopShow(true);
  541. }
  542. // check if show should pause on hover
  543. if(options.autoHover && !options.ticker){
  544. setAutoHover();
  545. }
  546. }
  547. // make the starting slide active
  548. if(options.moveSlideQty > 1){
  549. makeSlideActive(Math.ceil(currentSlide / options.moveSlideQty));
  550. }else{
  551. makeSlideActive(currentSlide);
  552. }
  553. // check for finite show and if controls should be hidden
  554. checkEndControls();
  555. // show captions
  556. if(options.captions){
  557. showCaptions();
  558. }
  559. // perform the callback function
  560. options.onAfterSlide(currentSlide, $children.length, $children.eq(currentSlide));
  561. }
  562. /**
  563. * Destroy the current slideshow
  564. */
  565. this.destroyShow = function(){
  566. // stop the auto show
  567. clearInterval(interval);
  568. // remove any controls / pagers that have been appended
  569. $('.bx-next, .bx-prev, .bx-pager, .bx-auto', $outerWrapper).remove();
  570. // unwrap all bx-wrappers
  571. $parent.unwrap().unwrap().removeAttr('style');
  572. // remove any styles that were appended
  573. $parent.children().removeAttr('style').not('.pager').remove();
  574. // remove any childrent that were appended
  575. $children.removeClass('pager');
  576. }
  577. /**
  578. * Reload the current slideshow
  579. */
  580. this.reloadShow = function(){
  581. base.destroyShow();
  582. base.initShow();
  583. }
  584. // PRIVATE FUNCTIONS
  585. /**
  586. * Creates all neccessary styling for the slideshow
  587. */
  588. function initCss(){
  589. // layout the children
  590. setChildrenLayout(options.startingSlide);
  591. // CSS for horizontal mode
  592. if(options.mode == 'horizontal'){
  593. // wrap the <ul> in div that acts as a window and make the <ul> uber wide
  594. $parent
  595. .wrap('<div class="'+options.wrapperClass+'" style="width:'+wrapperWidth+'px; position:relative;"></div>')
  596. .wrap('<div class="bx-window" style="position:relative; overflow:hidden; width:'+wrapperWidth+'px;"></div>')
  597. .css({
  598. width: '999999px',
  599. position: 'relative',
  600. left: '-'+(origLeft)+'px'
  601. });
  602. $parent.children().css({
  603. width: childrenWidth,
  604. 'float': 'left',
  605. listStyle: 'none'
  606. });
  607. $outerWrapper = $parent.parent().parent();
  608. $children.addClass('pager');
  609. // CSS for vertical mode
  610. }else if(options.mode == 'vertical'){
  611. // wrap the <ul> in div that acts as a window and make the <ul> uber tall
  612. $parent
  613. .wrap('<div class="'+options.wrapperClass+'" style="width:'+childrenMaxWidth+'px; position:relative;"></div>')
  614. .wrap('<div class="bx-window" style="width:'+childrenMaxWidth+'px; height:'+wrapperHeight+'px; position:relative; overflow:hidden;"></div>')
  615. .css({
  616. height: '999999px',
  617. position: 'relative',
  618. top: '-'+(origTop)+'px'
  619. });
  620. $parent.children().css({
  621. listStyle: 'none',
  622. height: childrenMaxHeight
  623. });
  624. $outerWrapper = $parent.parent().parent();
  625. $children.addClass('pager');
  626. // CSS for fade mode
  627. }else if(options.mode == 'fade'){
  628. // wrap the <ul> in div that acts as a window
  629. $parent
  630. .wrap('<div class="'+options.wrapperClass+'" style="width:'+childrenMaxWidth+'px; position:relative;"></div>')
  631. .wrap('<div class="bx-window" style="height:'+childrenMaxHeight+'px; width:'+childrenMaxWidth+'px; position:relative; overflow:hidden;"></div>');
  632. $parent.children().css({
  633. listStyle: 'none',
  634. position: 'absolute',
  635. top: 0,
  636. left: 0,
  637. zIndex: 98
  638. });
  639. $outerWrapper = $parent.parent().parent();
  640. $children.not(':eq('+currentSlide+')').fadeTo(0, 0);
  641. $children.eq(currentSlide).css('zIndex', 99);
  642. }
  643. // if captions = true setup a div placeholder
  644. if(options.captions && options.captionsSelector == null){
  645. $outerWrapper.append('<div class="bx-captions"></div>');
  646. }
  647. }
  648. /**
  649. * Depending on mode, lays out children in the proper setup
  650. */
  651. function setChildrenLayout(){
  652. // lays out children for horizontal or vertical modes
  653. if(options.mode == 'horizontal' || options.mode == 'vertical'){
  654. // get the children behind
  655. var $prependedChildren = getArraySample($children, 0, options.moveSlideQty, 'backward');
  656. // add each prepended child to the back of the original element
  657. $.each($prependedChildren, function(index) {
  658. $parent.prepend($(this));
  659. });
  660. // total number of slides to be hidden after the window
  661. var totalNumberAfterWindow = ($children.length + options.moveSlideQty) - 1;
  662. // number of original slides hidden after the window
  663. var pagerExcess = $children.length - options.displaySlideQty;
  664. // number of slides to append to the original hidden slides
  665. var numberToAppend = totalNumberAfterWindow - pagerExcess;
  666. // get the sample of extra slides to append
  667. var $appendedChildren = getArraySample($children, 0, numberToAppend, 'forward');
  668. if(options.infiniteLoop){
  669. // add each appended child to the front of the original element
  670. $.each($appendedChildren, function(index) {
  671. $parent.append($(this));
  672. });
  673. }
  674. }
  675. }
  676. /**
  677. * Sets all variables associated with the controls
  678. */
  679. function setControlsVars(){
  680. // check if text or images should be used for controls
  681. // check "next"
  682. if(options.nextImage != ''){
  683. nextContent = options.nextImage;
  684. nextType = 'image';
  685. }else{
  686. nextContent = options.nextText;
  687. nextType = 'text';
  688. }
  689. // check "prev"
  690. if(options.prevImage != ''){
  691. prevContent = options.prevImage;
  692. prevType = 'image';
  693. }else{
  694. prevContent = options.prevText;
  695. prevType = 'text';
  696. }
  697. // show the controls
  698. showControls(nextType, nextContent, prevType, prevContent);
  699. }
  700. /**
  701. * Puts slideshow into auto mode
  702. *
  703. * @param int pause number of ms the slideshow will wait between slides
  704. * @param string direction 'forward', 'backward' sets the direction of the slideshow (forward/backward)
  705. * @param bool controls determines if start/stop controls will be displayed
  706. */
  707. function setAutoInterval(){
  708. if(options.auto){
  709. // finite loop
  710. if(!options.infiniteLoop){
  711. if(options.autoDirection == 'next'){
  712. interval = setInterval(function(){
  713. currentSlide += options.moveSlideQty;
  714. // if currentSlide has exceeded total number
  715. if(currentSlide > lastSlide){
  716. currentSlide = currentSlide % $children.length;
  717. }
  718. base.goToSlide(currentSlide, false);
  719. }, options.pause);
  720. }else if(options.autoDirection == 'prev'){
  721. interval = setInterval(function(){
  722. currentSlide -= options.moveSlideQty;
  723. // if currentSlide is smaller than zero
  724. if(currentSlide < 0){
  725. negativeOffset = (currentSlide % $children.length);
  726. if(negativeOffset == 0){
  727. currentSlide = 0;
  728. }else{
  729. currentSlide = ($children.length) + negativeOffset;
  730. }
  731. }
  732. base.goToSlide(currentSlide, false);
  733. }, options.pause);
  734. }
  735. // infinite loop
  736. }else{
  737. if(options.autoDirection == 'next'){
  738. interval = setInterval(function(){
  739. base.goToNextSlide(false);
  740. }, options.pause);
  741. }else if(options.autoDirection == 'prev'){
  742. interval = setInterval(function(){
  743. base.goToPreviousSlide(false);
  744. }, options.pause);
  745. }
  746. }
  747. }else if(options.ticker){
  748. options.tickerSpeed *= 10;
  749. // get the total width of the original show
  750. $('.pager', $outerWrapper).each(function(index) {
  751. origShowWidth += $(this).width();
  752. origShowHeight += $(this).height();
  753. });
  754. // if prev start the show from the last slide
  755. if(options.tickerDirection == 'prev' && options.mode == 'horizontal'){
  756. $parent.css('left', '-'+(origShowWidth+origLeft)+'px');
  757. }else if(options.tickerDirection == 'prev' && options.mode == 'vertical'){
  758. $parent.css('top', '-'+(origShowHeight+origTop)+'px');
  759. }
  760. if(options.mode == 'horizontal'){
  761. // get the starting left position
  762. tickerLeft = parseInt($parent.css('left'));
  763. // start the ticker
  764. moveTheShow(tickerLeft, origShowWidth, options.tickerSpeed);
  765. }else if(options.mode == 'vertical'){
  766. // get the starting top position
  767. tickerTop = parseInt($parent.css('top'));
  768. // start the ticker
  769. moveTheShow(tickerTop, origShowHeight, options.tickerSpeed);
  770. }
  771. // check it tickerHover applies
  772. if(options.tickerHover){
  773. setTickerHover();
  774. }
  775. }
  776. }
  777. function moveTheShow(leftCss, distance, speed){
  778. // if horizontal
  779. if(options.mode == 'horizontal'){
  780. // if next
  781. if(options.tickerDirection == 'next'){
  782. $parent.animate({'left': '-='+distance+'px'}, speed, 'linear', function(){
  783. $parent.css('left', leftCss);
  784. moveTheShow(leftCss, origShowWidth, options.tickerSpeed);
  785. });
  786. // if prev
  787. }else if(options.tickerDirection == 'prev'){
  788. $parent.animate({'left': '+='+distance+'px'}, speed, 'linear', function(){
  789. $parent.css('left', leftCss);
  790. moveTheShow(leftCss, origShowWidth, options.tickerSpeed);
  791. });
  792. }
  793. // if vertical
  794. }else if(options.mode == 'vertical'){
  795. // if next
  796. if(options.tickerDirection == 'next'){
  797. $parent.animate({'top': '-='+distance+'px'}, speed, 'linear', function(){
  798. $parent.css('top', leftCss);
  799. moveTheShow(leftCss, origShowHeight, options.tickerSpeed);
  800. });
  801. // if prev
  802. }else if(options.tickerDirection == 'prev'){
  803. $parent.animate({'top': '+='+distance+'px'}, speed, 'linear', function(){
  804. $parent.css('top', leftCss);
  805. moveTheShow(leftCss, origShowHeight, options.tickerSpeed);
  806. });
  807. }
  808. }
  809. }
  810. /**
  811. * Sets all variables associated with the controls
  812. */
  813. function setAutoControlsVars(){
  814. // check if text or images should be used for controls
  815. // check "start"
  816. if(options.startImage != ''){
  817. startContent = options.startImage;
  818. startType = 'image';
  819. }else{
  820. startContent = options.startText;
  821. startType = 'text';
  822. }
  823. // check "stop"
  824. if(options.stopImage != ''){
  825. stopContent = options.stopImage;
  826. stopType = 'image';
  827. }else{
  828. stopContent = options.stopText;
  829. stopType = 'text';
  830. }
  831. // show the controls
  832. showAutoControls(startType, startContent, stopType, stopContent);
  833. }
  834. /**
  835. * Handles hover events for auto shows
  836. */
  837. function setAutoHover(){
  838. // hover over the slider window
  839. $outerWrapper.find('.bx-window').hover(function() {
  840. if(autoPlaying){
  841. base.stopShow(false);
  842. }
  843. }, function() {
  844. if(autoPlaying){
  845. base.startShow(false);
  846. }
  847. });
  848. }
  849. /**
  850. * Handles hover events for ticker mode
  851. */
  852. function setTickerHover(){
  853. // on hover stop the animation
  854. $parent.hover(function() {
  855. if(autoPlaying){
  856. base.stopTicker(false);
  857. }
  858. }, function() {
  859. if(autoPlaying){
  860. base.startTicker(false);
  861. }
  862. });
  863. }
  864. /**
  865. * Handles fade animation
  866. */
  867. function setChildrenFade(){
  868. // fade out any other child besides the current
  869. $children.not(':eq('+currentSlide+')').fadeTo(options.speed, 0).css('zIndex', 98);
  870. // fade in the current slide
  871. $children.eq(currentSlide).css('zIndex', 99).fadeTo(options.speed, 1, function(){
  872. isWorking = false;
  873. // ie fade fix
  874. if(jQuery.browser.msie){
  875. $children.eq(currentSlide).get(0).style.removeAttribute('filter');
  876. }
  877. // perform the callback function
  878. options.onAfterSlide(currentSlide, $children.length, $children.eq(currentSlide));
  879. });
  880. };
  881. /**
  882. * Makes slide active
  883. */
  884. function makeSlideActive(number){
  885. if(options.pagerType == 'full' && options.pager){
  886. // remove all active classes
  887. $('a', $pager).removeClass(options.pagerActiveClass);
  888. // assign active class to appropriate slide
  889. $('a', $pager).eq(number).addClass(options.pagerActiveClass);
  890. }else if(options.pagerType == 'short' && options.pager){
  891. $('.bx-pager-current', $pager).html(currentSlide+1);
  892. }
  893. }
  894. /**
  895. * Displays next/prev controls
  896. *
  897. * @param string nextType 'image', 'text'
  898. * @param string nextContent if type='image', specify a filepath to the image. if type='text', specify text.
  899. * @param string prevType 'image', 'text'
  900. * @param string prevContent if type='image', specify a filepath to the image. if type='text', specify text.
  901. */
  902. function showControls(nextType, nextContent, prevType, prevContent){
  903. // create pager html elements
  904. var $nextHtml = $('<a href="" class="bx-next"></a>');
  905. var $prevHtml = $('<a href="" class="bx-prev"></a>');
  906. // check if next is 'text' or 'image'
  907. if(nextType == 'text'){
  908. $nextHtml.html(nextContent);
  909. }else{
  910. $nextHtml.html('<img src="'+nextContent+'" />');
  911. }
  912. // check if prev is 'text' or 'image'
  913. if(prevType == 'text'){
  914. $prevHtml.html(prevContent);
  915. }else{
  916. $prevHtml.html('<img src="'+prevContent+'" />');
  917. }
  918. // check if user supplied a selector to populate next control
  919. if(options.prevSelector){
  920. $(options.prevSelector).append($prevHtml);
  921. }else{
  922. $outerWrapper.append($prevHtml);
  923. }
  924. // check if user supplied a selector to populate next control
  925. if(options.nextSelector){
  926. $(options.nextSelector).append($nextHtml);
  927. }else{
  928. $outerWrapper.append($nextHtml);
  929. }
  930. // click next control
  931. $nextHtml.click(function() {
  932. base.goToNextSlide();
  933. return false;
  934. });
  935. // click prev control
  936. $prevHtml.click(function() {
  937. base.goToPreviousSlide();
  938. return false;
  939. });
  940. }
  941. /**
  942. * Displays the pager
  943. *
  944. * @param string type 'full', 'short'
  945. */
  946. function showPager(type){
  947. // sets up logic for finite multi slide shows
  948. var pagerQty = $children.length;
  949. // if we are moving more than one at a time and we have a finite loop
  950. if(options.moveSlideQty > 1){
  951. // if slides create an odd number of pages
  952. if($children.length % options.moveSlideQty != 0){
  953. // pagerQty = $children.length / options.moveSlideQty + 1;
  954. pagerQty = Math.ceil($children.length / options.moveSlideQty);
  955. // if slides create an even number of pages
  956. }else{
  957. pagerQty = $children.length / options.moveSlideQty;
  958. }
  959. }
  960. var pagerString = '';
  961. // check if custom build function was supplied
  962. if(options.buildPager){
  963. for(var i=0; i<pagerQty; i++){
  964. pagerString += options.buildPager(i, $children.eq(i * options.moveSlideQty));
  965. }
  966. // if not, use default pager
  967. }else if(type == 'full'){
  968. // build the full pager
  969. for(var i=1; i<=pagerQty; i++){
  970. pagerString += '<a href="" class="pager-link pager-'+i+'">'+i+'</a>';
  971. }
  972. }else if(type == 'short') {
  973. // build the short pager
  974. pagerString = '<span class="bx-pager-current">'+(options.startingSlide+1)+'</span> '+options.pagerShortSeparator+' <span class="bx-pager-total">'+$children.length+'<span>';
  975. }
  976. // check if user supplied a pager selector
  977. if(options.pagerSelector){
  978. $(options.pagerSelector).append(pagerString);
  979. $pager = $(options.pagerSelector);
  980. }else{
  981. var $pagerContainer = $('<div class="bx-pager"></div>');
  982. $pagerContainer.append(pagerString);
  983. // attach the pager to the DOM
  984. if(options.pagerLocation == 'top'){
  985. $outerWrapper.prepend($pagerContainer);
  986. }else if(options.pagerLocation == 'bottom'){
  987. $outerWrapper.append($pagerContainer);
  988. }
  989. // cache the pager element
  990. $pager = $('.bx-pager', $outerWrapper);
  991. }
  992. $pager.children().click(function() {
  993. // only if pager is full mode
  994. if(options.pagerType == 'full'){
  995. // get the index from the link
  996. var slideIndex = $pager.children().index(this);
  997. // accomodate moving more than one slide
  998. if(options.moveSlideQty > 1){
  999. slideIndex *= options.moveSlideQty;
  1000. }
  1001. base.goToSlide(slideIndex);
  1002. }
  1003. return false;
  1004. });
  1005. }
  1006. /**
  1007. * Displays captions
  1008. */
  1009. function showCaptions(){
  1010. // get the title from each image
  1011. var caption = $('img', $children.eq(currentSlide)).attr('title');
  1012. // if the caption exists
  1013. if(caption != ''){
  1014. // if user supplied a selector
  1015. if(options.captionsSelector){
  1016. $(options.captionsSelector).html(caption);
  1017. }else{
  1018. $('.bx-captions', $outerWrapper).html(caption);
  1019. }
  1020. }else{
  1021. // if user supplied a selector
  1022. if(options.captionsSelector){
  1023. $(options.captionsSelector).html('&nbsp;');
  1024. }else{
  1025. $('.bx-captions', $outerWrapper).html('&nbsp;');
  1026. }
  1027. }
  1028. }
  1029. /**
  1030. * Displays start/stop controls for auto and ticker mode
  1031. *
  1032. * @param string type 'image', 'text'
  1033. * @param string next [optional] if type='image', specify a filepath to the image. if type='text', specify text.
  1034. * @param string prev [optional] if type='image', specify a filepath to the image. if type='text', specify text.
  1035. */
  1036. function showAutoControls(startType, startContent, stopType, stopContent){
  1037. // create pager html elements
  1038. $autoControls = $('<a href="" class="bx-start"></a>');
  1039. // check if start is 'text' or 'image'
  1040. if(startType == 'text'){
  1041. $startContent = startContent;
  1042. }else{
  1043. $startContent = '<img src="'+startContent+'" />';
  1044. }
  1045. // check if stop is 'text' or 'image'
  1046. if(stopType == 'text'){
  1047. $stopContent = stopContent;
  1048. }else{
  1049. $stopContent = '<img src="'+stopContent+'" />';
  1050. }
  1051. // check if user supplied a selector to populate next control
  1052. if(options.autoControlsSelector){
  1053. $(options.autoControlsSelector).append($autoControls);
  1054. }else{
  1055. $outerWrapper.append('<div class="bx-auto"></div>');
  1056. $('.bx-auto', $outerWrapper).html($autoControls);
  1057. }
  1058. // click start control
  1059. $autoControls.click(function() {
  1060. if(options.ticker){
  1061. if($(this).hasClass('stop')){
  1062. base.stopTicker();
  1063. }else if($(this).hasClass('start')){
  1064. base.startTicker();
  1065. }
  1066. }else{
  1067. if($(this).hasClass('stop')){
  1068. base.stopShow(true);
  1069. }else if($(this).hasClass('start')){
  1070. base.startShow(true);
  1071. }
  1072. }
  1073. return false;
  1074. });
  1075. }
  1076. /**
  1077. * Checks if show is in finite mode, and if slide is either first or last, then hides the respective control
  1078. */
  1079. function checkEndControls(){
  1080. if(!options.infiniteLoop && options.hideControlOnEnd){
  1081. // check previous
  1082. if(currentSlide == firstSlide){
  1083. $('.bx-prev', $outerWrapper).hide();
  1084. }else{
  1085. $('.bx-prev', $outerWrapper).show();
  1086. }
  1087. // check next
  1088. if(currentSlide == lastSlide){
  1089. $('.bx-next', $outerWrapper).hide();
  1090. }else{
  1091. $('.bx-next', $outerWrapper).show();
  1092. }
  1093. }
  1094. }
  1095. /**
  1096. * Returns the left offset of the slide from the parent container
  1097. */
  1098. function getSlidePosition(number, side){
  1099. if(side == 'left'){
  1100. var position = $('.pager', $outerWrapper).eq(number).position().left;
  1101. }else if(side == 'top'){
  1102. var position = $('.pager', $outerWrapper).eq(number).position().top;
  1103. }
  1104. return position;
  1105. }
  1106. /**
  1107. * Returns the width of the wrapper
  1108. */
  1109. function getWrapperWidth(){
  1110. var wrapperWidth = $firstChild.outerWidth() * options.displaySlideQty;
  1111. return wrapperWidth;
  1112. }
  1113. /**
  1114. * Returns the height of the wrapper
  1115. */
  1116. function getWrapperHeight(){
  1117. // if displaying multiple slides, multiple wrapper width by number of slides to display
  1118. var wrapperHeight = $firstChild.outerHeight() * options.displaySlideQty;
  1119. return wrapperHeight;
  1120. }
  1121. /**
  1122. * Returns a sample of an arry and loops back on itself if the end of the array is reached
  1123. *
  1124. * @param array array original array the sample is derived from
  1125. * @param int start array index sample will start
  1126. * @param int length number of items in the sample
  1127. * @param string direction 'forward', 'backward' direction the loop should travel in the array
  1128. */
  1129. function getArraySample(array, start, length, direction){
  1130. // initialize empty array
  1131. var sample = [];
  1132. // clone the length argument
  1133. var loopLength = length;
  1134. // determines when the empty array should start being populated
  1135. var startPopulatingArray = false;
  1136. // reverse the array if direction = 'backward'
  1137. if(direction == 'backward'){
  1138. array = $.makeArray(array);
  1139. array.reverse();
  1140. }
  1141. // loop through original array until the length argument is met
  1142. while(loopLength > 0){
  1143. // loop through original array
  1144. $.each(array, function(index, val) {
  1145. // check if length has been met
  1146. if(loopLength > 0){
  1147. // don't do anything unless first index has been reached
  1148. if(!startPopulatingArray){
  1149. // start populating empty array
  1150. if(index == start){
  1151. startPopulatingArray = true;
  1152. // add element to array
  1153. sample.push($(this).clone());
  1154. // decrease the length clone variable
  1155. loopLength--;
  1156. }
  1157. }else{
  1158. // add element to array
  1159. sample.push($(this).clone());
  1160. // decrease the length clone variable
  1161. loopLength--;
  1162. }
  1163. // if length has been met, break loose
  1164. }else{
  1165. return false;
  1166. }
  1167. });
  1168. }
  1169. return sample;
  1170. }
  1171. this.each(function(){
  1172. // make sure the element has children
  1173. if($(this).children().length > 0){
  1174. base.initShow();
  1175. }
  1176. });
  1177. return this;
  1178. }
  1179. jQuery.fx.prototype.cur = function(){
  1180. if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) {
  1181. return this.elem[ this.prop ];
  1182. }
  1183. var r = parseFloat( jQuery.css( this.elem, this.prop ) );
  1184. // return r && r > -10000 ? r : 0;
  1185. return r;
  1186. }
  1187. })(jQuery);