Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jquery animating width accordion style banner

I built this simple accordion style banner. Here's what it's supposed to do:

  • Grab <li> containing images from selected <ul>.
  • Divide them equally within the container (div.banner)
  • On 'mouseenter', add class .active to the hovered <li>
    • Shrink the other <li>s widths (half their original width).
    • Enlarge active <li> to new width (remainder after halving the others)
  • On 'mouseleave', all return to original widths.

Works fine until you swipe over multiple panes quickly. If you do, the last of the floated <li>'s break to the next line. It appears the total width of the panes is exceeding their container.

Rounding error while animating? Does it have something to do with animate's default 'swing' easing?

Fiddle: http://jsfiddle.net/UNFc4/

var banner = $('.banner');
var list_items = banner.find('li');
var banner_width = $(banner).width();
var num_of_images = $(banner).find('li').length;
var original_width = banner_width / num_of_images;
var half_width = (banner_width / num_of_images) / 2;

var init = function () {
    $(list_items).css('width', original_width);

    $(list_items).on('mouseenter', function () {
        $(this).addClass('active');
        doAnimation();

    });
    $(list_items).on('mouseleave', function () {
        resetAnimation();
        $(this).removeClass('active');
    });
}
var doAnimation = function () {
    $(list_items).not(".active").stop().animate({
        width: half_width + "px"
    }, 500);

    $(".active").stop().animate({
        width: (original_width + (half_width * (num_of_images - 1))) + "px"
    }, 500);
}
var resetAnimation = function () {
    $(list_items).stop().animate({
        width: original_width + "px"
    }, 500);
}
init();

I could fix it by changing this line, slowing the animation of the others, giving things time to equal out. But, I'd rather solve what's going on here, hopefully learning a bit more about how jQuery's animate() works.

 $(list_items).not(".active").stop().animate({
        width: half_width + "px"
    }, 480); // changed 500 to 480 
like image 595
Geomatic Avatar asked Dec 02 '25 12:12

Geomatic


1 Answers

For those interested, I realized I only needed the reset on the banner area. Now it works, as described, without all the jitteriness and the subsequent layout mis-alignments.

New Fiddle: http://jsfiddle.net/UNFc4/1/

$(list_items).on('mouseenter', function () {
        $(this).addClass('active');
        doAnimation();
    });
    $(list_items).on('mouseleave', function () {
        $(this).removeClass('active');
        doAnimation();
    });
    $(banner).on('mouseleave', function () {
        resetAnimation(); 
    });
like image 121
Geomatic Avatar answered Dec 05 '25 02:12

Geomatic



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!