bob_cobb
bob_cobb

Reputation: 2269

Making carousel not infinitely scroll

I wrote this infinite scrolling carousel, and I'm wondering what the best way to do non-infinite scrolling would be.

Right now, the user specifies how many items they would like to appear in view @ a time (in numSlide). So basically, the user clicks on the right arrows, it uses the .animate() method which calls either prevLoop or nextLoop. Either of those basically just pull the number of elements specified and moves them to either the beginning or end of the <ul></ul> accordingly.

I've got this far, but now I'm trying to introduce the option of turning off infinite scroll (e.g. show only the items in the list and once you get to the end of each side, it prevents calling prevLoop/nextLoop.

My idea is basically, set a variable called infinite. Within either of the click functions (rightClick() and leftClick()) check to see if infinite is true. If it is, use the normal scrolling code. Otherwise, I'm thinking of: taking the number of elements within the <ul> which is found within numElements, set a count variable to increment through each click, and check to see if the count is the same or less of the numElements. If it's > numElements, then I'd prevent either function from animating more. I feel like this would get pretty messy/busy quickly.

It'd be setup like:

    var count = numElements;
    function rightClick() {
    var cfirst = container.find('li').first(), //the current first element
        tomove = cfirst.nextLoop(numSlide - 1, true), //the elements that need to move
        nfirst = tomove.last().nextLoop(1, false); //the new first element

    /*
       Pretend we currently have [A, B, C, D, E, F, G, H, I] and numSlide is 3
       cfirst === [A]
       tomove === [A, B, C]
       nfirst === [D]
    */

    var indent = cfirst.offset().left - nfirst.offset().left;

    if (infinite) {
    ul.not(':animated').animate({ // not:animated makes sure we only get one @ a time
        'left': indent
    }, 'fast', function() {
        tomove.appendTo(ul); //Move them to the end of the UL
        ul.css({ // left indent of ul
            'left': 0
        });
    });
} else {
     // Infinite is turned off, handle it in here
    count = count -1;
    // Animate numElements - numSlide
}
}

Anyone have any other ideas? As it is here is a working demo:

http://jsfiddle.net/someprimetime/AYfhn/

Upvotes: 0

Views: 895

Answers (1)

Peter-Paul van Gemerden
Peter-Paul van Gemerden

Reputation: 7011

One way to handle this would be to keep a reference to the "last" <li> (as it was before any <li>s were moved) and use .index() to find its current position in the <ul>, like this:

var lastIndex = last.index();

if (infinite || (lastIndex + 1 >= rowSize + numSlide)) {
    // animate
} else if (lastIndex >= rowSize) {
    // animate using smaller numSlide
} else {
    // don't animate
}

One other thing:

You should consider turning your code into a jQuery plugin. They're very easy to write. You don't need to distribute it or anything; it's just to make it easier make it easier to work on. In particular, you would benefit from options and defaults, and you could keep state (e.g. the "last" <li>) using the data method.

Upvotes: 1

Related Questions