var oCarousel = ''; $(function () { var _settings = { divContainer: "#carousel", btPrevSlide: ".prevSlide", btNextSlide: ".nextSlide", direction: 0, endReachedFunc: function () { console.log('end reached') } }; oCarousel = new ContinuousCarouselV2(_settings, 1); }); var ContinuousCarouselV2 = function (pSettings, pAutoRun) { this.hInterval = 0; this.numItems = 0; this.ctItems = 0; this.DIR = { RtoL: 0, LtoR: 1, STOP: 2 }; this.iniDirection = 0; this.iniStep = 0; this.currDirection = 0; this.$ulContainer = ''; this.currItemWidth = 0; this.currPos = 0; this.settings = { // jQuery selectors divContainer: '', // Required. jQuery Div ID. With overflow:hidden. e.g.: #carousel ulContainer: '', // Optional btPrevSlide: '', btNextSlide: '', // endReachedFunc: '', // Function to invoke when all items are slid to one side direction: 0, // 0: right to left | 1: left to right | 2: No automatic sliding step: 1, interval: 30, fastStep: 3, fastInterval: 5 }; this.options = {}; this.init = function (pSettings, pAutoRun) { var _me = this, _opts = _me.options = (pSettings) ? $.extend({}, _me.settings, pSettings) : $.extend({}, _me.settings); if (!_opts.ulContainer) { _opts.ulContainer = _opts.divContainer + " ul"; } _me.currSpeed = _opts.speed; _me.currDirection = _me.iniDirection = _opts.direction; _me.iniStep = _opts.step; _me.$ulContainer = $(_opts.ulContainer).css({ 'width': 999999, 'position': 'relative' }); _me.bindEvents(); if (_opts.endReachedFunc) { _me.computeNumItems() } if (pAutoRun) { _me.run() } }; this.bindEvents = function () { var _me = this, _opts = _me.options; _me.$ulContainer.hover(function () { _me.stopAnim() }, function () { _me.resumeAnim() }); $(_opts.btNextSlide).hover(function (e) { _me.setLoop(1, _me.DIR.RtoL) }, function () { _me.setLoop(0, _me.iniDirection) }); $(_opts.btPrevSlide).hover(function (e) { _me.setLoop(1, _me.DIR.LtoR) }, function () { _me.setLoop(0, _me.iniDirection) }); }; this.run = function () { var _me = this, _LtoR = (_me.options.direction == _me.DIR.LtoR); (_LtoR) ? _me.setLtoR() : _me.setRtoL(); _me.setLoop(0, _LtoR); }; this.setLoop = function (pFast, pDirection) { var _me = this, _opts = _me.options, _interval = (pFast) ? _opts.fastInterval : _opts.interval; _opts.step = (pFast) ? _opts.fastStep : _me.iniStep; if (_me.hInterval) { clearRequestInterval(_me.hInterval) } //if (_me.hInterval) { clearInterval(_me.hInterval) } _me.currDirection = pDirection; _me.hInterval = requestInterval(function () { _me.loop() }, _interval); //_me.hInterval = setInterval(function () { // _me.loop() //}, _interval); }; this.stopAnim = function () { this.currDirection = this.DIR.STOP; }; this.resumeAnim = function () { this.currDirection = this.iniDirection; }; this.setRtoL = function () { var _me = this, _opts = _me.options; _me.currItemWidth = $(_me.$ulContainer).children(':first').outerWidth(true); _me.currPos = 0; _me.$ulContainer.css('margin-left', 0); }; this.setLtoR = function () { var _me = this, _opts = _me.options, _$ul = _me.$ulContainer, _$currItem = _$ul.children(':last'); _me.currItemWidth = _$currItem.outerWidth(true); _me.currPos = -1 * _me.currItemWidth; _$ul.css('margin-left', _me.currPos); _$currItem.prependTo(_$ul); }; this.loop = function () { var _me = this, _opts = _me.options, _$ul = _me.$ulContainer, _currItemWidthNeg; if (_me.currDirection != _me.DIR.STOP) { if (_me.currDirection == _me.DIR.RtoL) { // Right To Left _me.currPos -= _opts.step; _currItemWidthNeg = -1 * _me.currItemWidth; if (_me.currPos < _currItemWidthNeg) { _me.currPos = _currItemWidthNeg } _$ul.css('margin-left', _me.currPos); if (_me.currPos == _currItemWidthNeg) { _$ul.children(':first').appendTo(_$ul); _me.setRtoL(); if (_opts.endReachedFunc) { _me.ctrlCounter(_me.currDirection) } } } else { _me.currPos += _opts.step; if (_me.currPos > 0) { _me.currPos = 0; } _$ul.css('margin-left', _me.currPos); if (_me.currPos == 0) { _me.setLtoR(); if (_opts.endReachedFunc) { _me.ctrlCounter(_me.currDirection) } } } } }; this.computeNumItems = function (pNum) { this.numItems = pNum || this.$ulContainer.children().length; this.ctItems = 0; }; this.ctrlCounter = function (pDirection) { var _me = this, _opts = _me.options; _me.ctItems += (pDirection == _opts.direction) ? 1 : -1; if (Math.abs(_me.ctItems) >= _me.numItems - 1) { _me.ctItems = 0; _opts.endReachedFunc(); } }; // this.init(pSettings, pAutoRun); }; /* * Drop in replace functions for setTimeout() & setInterval() that * make use of requestAnimationFrame() for performance where available * http://www.joelambert.co.uk * Copyright 2011, Joe Lambert. * Free to use under the MIT license. * http://www.opensource.org/licenses/mit-license.php */ // requestAnimationFrame() shim by Paul Irish // http://paulirish.com/2011/requestanimationframe-for-smart-animating/ window.requestAnimFrame = (function() { return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(/* function */ callback, /* DOMElement */ element){ window.setTimeout(callback, 1000 / 60); }; })(); /** * Behaves the same as setInterval except uses requestAnimationFrame() where possible for better performance * @param {function} fn The callback function * @param {int} delay The delay in milliseconds */ window.requestInterval = function(fn, delay) { if( !window.requestAnimationFrame && !window.webkitRequestAnimationFrame && !(window.mozRequestAnimationFrame && window.mozCancelRequestAnimationFrame) && // Firefox 5 ships without cancel support !window.oRequestAnimationFrame && !window.msRequestAnimationFrame) return window.setInterval(fn, delay); var start = new Date().getTime(), handle = new Object(); function loop() { handle.value = requestAnimFrame(loop); var current = new Date().getTime(), delta = current - start; if(delta >= delay) { fn.call(); start = new Date().getTime(); } }; handle.value = requestAnimFrame(loop); return handle; } /** * Behaves the same as clearInterval except uses cancelRequestAnimationFrame() where possible for better performance * @param {int|object} fn The callback function */ window.clearRequestInterval = function(handle) { window.cancelAnimationFrame ? window.cancelAnimationFrame(handle.value) : window.webkitCancelAnimationFrame ? window.webkitCancelAnimationFrame(handle.value) : window.webkitCancelRequestAnimationFrame ? window.webkitCancelRequestAnimationFrame(handle.value) : /* Support for legacy API */ window.mozCancelRequestAnimationFrame ? window.mozCancelRequestAnimationFrame(handle.value) : window.oCancelRequestAnimationFrame ? window.oCancelRequestAnimationFrame(handle.value) : window.msCancelRequestAnimationFrame ? window.msCancelRequestAnimationFrame(handle.value) : clearInterval(handle); }; /** * Behaves the same as setTimeout except uses requestAnimationFrame() where possible for better performance * @param {function} fn The callback function * @param {int} delay The delay in milliseconds */ window.requestTimeout = function(fn, delay) { if( !window.requestAnimationFrame && !window.webkitRequestAnimationFrame && !(window.mozRequestAnimationFrame && window.mozCancelRequestAnimationFrame) && // Firefox 5 ships without cancel support !window.oRequestAnimationFrame && !window.msRequestAnimationFrame) return window.setTimeout(fn, delay); var start = new Date().getTime(), handle = new Object(); function loop(){ var current = new Date().getTime(), delta = current - start; delta >= delay ? fn.call() : handle.value = requestAnimFrame(loop); }; handle.value = requestAnimFrame(loop); return handle; }; /** * Behaves the same as clearTimeout except uses cancelRequestAnimationFrame() where possible for better performance * @param {int|object} fn The callback function */ window.clearRequestTimeout = function(handle) { window.cancelAnimationFrame ? window.cancelAnimationFrame(handle.value) : window.webkitCancelAnimationFrame ? window.webkitCancelAnimationFrame(handle.value) : window.webkitCancelRequestAnimationFrame ? window.webkitCancelRequestAnimationFrame(handle.value) : /* Support for legacy API */ window.mozCancelRequestAnimationFrame ? window.mozCancelRequestAnimationFrame(handle.value) : window.oCancelRequestAnimationFrame ? window.oCancelRequestAnimationFrame(handle.value) : window.msCancelRequestAnimationFrame ? window.msCancelRequestAnimationFrame(handle.value) : clearTimeout(handle); };
<div id="container"> <div class="arrow"><a href="#" class="prevSlide">Prev</a> </div> <div id="carousel" style="float:left"> <ul> <li style="width:130px"> <h3>1</h3> </li> <li style="width:340px"> <h3>2</h3> </li> <li style="width:260px"> <h3>3</h3> </li> <li style="width:200px"> <h3>4</h3> </li> <li style="width:380px"> <h3>5</h3> </li> </ul> </div> <div class="arrow"><a href="#" class="nextSlide">Next</a> </div> </div>
#container { clear:both; float:left; width:940px; } #container .arrow { float:left; margin:10px; line-height:230px; font-size:large; font-weight:bold; } #carousel { width: 350px; overflow:hidden; height:252px; border:1px solid black; } #carousel ul { width: 999999px; padding: 0; margin: 0; } #carousel ul li { width:239px; text-align: center; height: 250px; list-style: none; float: left; line-height:228px; border:1px solid red; }