Omer
Omer

Reputation: 1796

A little bug in my custom jQuery carousel

I'm creating a custom jQuery carousel and its coming out really well :)

But found a little glitch / bug in it. When you click on Prev / Next like a normal user do, it works fine but when you click on it like a robot with hyper speed, it slides blank spaces.

I'm sharing my code here and also providing the JSFiddle Link. It would be nice if someone could help me out or give me better suggestions to make it more pro :)

HTML:

<div id="my_carousel">
    <div class="carousel">
      <ul>
        <li style="background:red;"></li>
        <li style="background:green;"></li>
        <li style="background:blue;"></li>
        <li style="background:purple;"></li>
      </ul>
    </div>
</div>

CSS:

* {
padding: 0;
margin: 0;
}
#my_carousel {
padding: 0 15px;
position: relative;
height: 100px;
display: inline-block;
}
.carousel {
overflow:hidden;
position: relative;
height: 100px;
}
.carousel ul {
list-style: none;
position: absolute;
left: 0;
top: 0;
}
.carousel ul li {
width: 100px;
height: 100px;
float: left;
}
.controls {
position: absolute;
top: 50%;
left: 0;
margin: -10px 0 0;
width: 100%;
}
.prev {
float: left;
}
.next {
float: right;
}

JQUERY:

(function ($) {
$.fn.my_carousel = function (defaults) {

    // Default settings
    var settings = $.extend({
        layout: 'hort',
        visible_items: 2,
        item_width: this.find('li').width(),
        reel_width: this.find('li').length
    }, defaults);

    if (settings.layout === 'hort') {

        // Adding Prev/Next links 
        this.find('.carousel').after('<div class="controls"><a href="#" class="prev">&lt;</a><a href="#" class="next">&gt;</a></div>');

        // Setting window / reel /controls width
        this.find('.carousel').width(settings.item_width * settings.visible_items);
        this.find('ul').width(settings.reel_width * settings.item_width);

        // Slide control
        $('.controls a').click(function () {
            var pos = $(this).parents(this).find('ul').offset().left;
            if ($(this).hasClass('next')) {
                if (pos >= ((settings.item_width * settings.visible_items) - (settings.reel_width * settings.item_width) + settings.item_width)) {
                    $(this).parents(this).find('ul').animate({
                        left: '-=' + settings.item_width + 'px'
                    }, 200);
                } else {
                    return false;
                }
            } else {
                if (pos <= 0) {
                    $(this).parents(this).find('ul').animate({
                        left: '+=' + settings.item_width + 'px'
                    }, 200);
                } else {
                    return false;
                }
            }
        });
    }

};
})(jQuery);

$('#my_carousel').my_carousel();

Upvotes: 0

Views: 77

Answers (1)

EdenSource
EdenSource

Reputation: 3387

This behavior is caused by your if() statement, which is checking your item's left position.

When you quickly click several times on the previous button (for exemple), left value is still animated and has not reached 0 and the next click is happening again.

Please see a solution I can give you using kind of pagination:

//ADDED CODE
var currentIndex = 1;
var totalItem = $('.carousel ul li').length;
var totalIndex = totalItem - 1;



// Slide control
$('.controls a').click(function () {
    var pos = $(this).parents(this).find('ul').offset().left;
    if ($(this).hasClass('next')) {

        //REMOVED
        //if (pos >= ((settings.item_width * settings.visible_items) - (settings.reel_width * settings.item_width) + settings.item_width)) { 
        if (currentIndex != totalIndex) { //ADDED
            $(this).parents(this).find('ul').animate({
                left: '-=' + settings.item_width + 'px'
            }, 200);
            currentIndex++;//ADDED
        } else {
            return false;
        }
    } else {

        //REMOVED
        //if (pos <= 0) {

        if (currentIndex != 1) { //ADDED
            $(this).parents(this).find('ul').animate({
                left: '+=' + settings.item_width + 'px'
            }, 200);
            currentIndex--;//ADDED
        } else {
            return false;
        }
    }
});

Live exemple


Edit 1:

Since you want to be able to manage number of displayed items, here is the updated code. I added var displayedItems = 4; to the very top of the code that is used in "Default settings" :

// Default settings
    var settings = $.extend({
        layout: 'hort',
        visible_items: displayedItems,
        item_width: this.find('li').width(),
        reel_width: this.find('li').length
    }, defaults);

And also used to calculate totalIndex :

var totalIndex = totalItem-(displayedItems-1);

Upvotes: 3

Related Questions