問題は、完全に同期されていない2つの独立したアニメーションが実行されており、2つのアニメーションの合計パーセンテージが常に100%未満であると予想していることです。両方を同時に開始すると、これが発生しない場合があり、合計が100%を超えるとすぐに、最後の行が次の行にプッシュされます。
最も簡単な回避策は、成長しているものをわずかに遅らせて、合計が常に100%未満になるようにすることです。2番目のアニメーションに.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');
}
おそらく最良の解決策は、まったく同じアニメーション(2つではなく1つのアニメーションのみ)で両方の幅のパーセンテージを変更して、常に完全に同期するカスタムアニメーションです。
これがカスタムアニメーションです。成長している要素のアニメーションを削除し、代わりに短い要素すべてにステップ関数コールバックを追加します。step関数は、要素の1つがアニメーションのサイズを変更するたびに呼び出されます。そのステップ関数では、その時点での短い要素の幅を合計し、長い要素を設定して、毎回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/