问题是您有两个不完全同步的独立动画正在运行,并且您希望两者的总百分比始终小于 100%。当你同时启动它们时,有时这不会发生,一旦总数超过 100%,最后一个就会被推到下一行。
最简单的解决方法是稍微延迟你正在增长的那个,这样总数总是小于 100%。您可以看到在第二个动画中添加了 .delay(50) 以确保增长的元素始终位于收缩的元素之后,因此总数始终小于 100%。工作演示:http: //jsfiddle.net/jfriend00/Fkb5K/。
添加的代码片段.delay(50)
:
if (!$el.hasClass('current'))
{
// Animate other columns to smaller size
$otherItems
.removeClass('curCol')
.stop(true)
.animate({ 'width': $closedItemsWidth }, 500, 'linear')
.css({"cursor":"pointer"});
// Animate current column to larger size
$el
.addClass('curCol')
.stop(true)
.delay(50)
.animate({ 'width' : $openItemWidth }, 500, 'linear')
.css({'cursor' : 'default'});
// Make sure the correct column is current
$otherItems.removeClass('curCol');
$el.addClass('curCol');
}
可能最好的解决方案是自定义动画,在完全相同的动画中更改两个宽度百分比(只有一个动画,而不是两个),因此它们始终完美同步。
这是一个自定义动画。它会删除您正在增长的元素的动画,而是在所有较短的元素上添加一个步进函数回调。每当元素之一在动画中更改大小时,都会调用 step 函数。在那个阶梯函数中,它会在那个时间点对较短元素的宽度求和,并设置较长的元素来精确跟踪它,每次都达到 100% 的完美总和。
// On click
$grid.delegate('#grid > .col', 'click', function () {
// Settings
var $el = $(this);
var $allItems = $grid.children('.col');
var $otherItems = $allItems.not($el);
if (!$el.hasClass('current')) {
// Animate other columns to smaller size
$otherItems.stop(true)
.removeClass('curCol')
.animate({ 'width': $closedItemsWidth}, {step: function(prop, fx) {
var cumWidth = 0;
var item = this;
$otherItems.each(function() {
// haven't changed the width of this item yet, so use new width
if (this == item) {
cumWidth += fx.now;
} else {
cumWidth += parseFloat(this.style.width);
}
});
$el.css({width: (100 - cumWidth) + '%'});
}, duration: 500 }, 'linear')
.css({"cursor":"pointer"});
// Animate current column to larger size
$el.addClass('curCol').css({'cursor' : 'default'});
}
})
在这里工作演示:http: //jsfiddle.net/jfriend00/7zubL/