这是我的解决方案。
在您现有的标记上,我添加了一个包装器划分来计算包装器内盒子的位置。像这样
<div id="wrapper">
<div class="block">
<h2>I'm block 1</h2>
</div>
....
</div>
为了保持块的流动性,我创建了一个函数来将块定位在包装上。这是块位置的函数:
var reposition = function() {
wrapper = $("#wrapper");
console.log(wrapper.innerWidth());
pLeft = 0;
pTop = 0;
maxRowHeight = 0;
$(".block").each(function(){
if($(this).data('active')) {
$(this).data('top', pTop);
$(this).data('left', pLeft);
} else {
$(this).stop(0,0).animate({
'top' : pTop + 'px',
'left' : pLeft + 'px'
});
}
pLeft += $(this).outerWidth() + parseInt($(this).css('marginLeft'));
if($(this).height() > maxRowHeight) maxRowHeight = $(this).outerHeight() + parseInt($(this).css('marginTop')); //Find out the longest block on the row
if(pLeft + $(this).next().outerWidth() + parseInt($(this).next().css('marginLeft')) >= wrapper.innerWidth()) {
pLeft = 0;
pTop += maxRowHeight;
maxRowHeight = 0;
}
});
};
最后,切换块的脚本
$(".block").click(function() {
$(this).siblings().slideToggle('slow'); //Toggle other blocks
if(!$(this).data('active')){ //if the block is not active
$(this).data('left', $(this).position().left); //sets its left
$(this).data('top', $(this).position().top); // and top position
$(this).animate({ //animate at the top and bottom
top:0,
left:0
},'slow');
$(this).data('active',true);
}else{
$(this).animate({ //animate to its last known position
top:$(this).data('top'),
left:$(this).data('left')
},'slow');
$(this).data('active',false);
}
});
Demos
-
Demo http://jsfiddle.net/Starx/GC3FX/14/[Full] http://jsfiddle.net/Starx/GC3FX/14/show(调整其大小以查看保持的流畅性)
-
Demo http://jsfiddle.net/Starx/wy6mv/3[Full] http://jsfiddle.net/Starx/wy6mv/3/show(显示可变高度的版本)
以下是该解决方案提供的内容:
- 记住最后一个位置并逐渐以动画方式到达/离开该位置
- 块位置在加载和每次调整大小时进行计算和动画
- 重新定位发生于
$(window).resize()
thus 维持液体尽管使用了绝对位置,但块的性质
- Support variable heights
- 对现有标记和 CSS 进行微小更改
还修复了 Gaby 提出的两个问题
- 独立核算每个区块保证金
- 调整大小后重新计算元素的位置