我能想到的最好的方法如下:
var toggleMinHeight = 30,
duration = 2000,
easing = 'swing';
$('.toggles').each(
function(){
$(this).attr('data-height',$(this).height());
}).click(
function(){
var curH = $(this).height();
if ($(this).is(':animated')){
return false;
}
else if (curH == $(this).attr('data-height')) {
$(this).animate(
{
'height' : toggleMinHeight
}, duration, easing);
}
else if (curH == toggleMinHeight){
$(this).animate(
{
'height' : $(this).attr('data-height')
}, duration, easing);
}
});
JS Fiddle demo.
这个演示有一些问题,但是:
- 没有超出基本 jQuery 库指定的缓动功能(提供对“swing”和“linear”的访问),但是可以通过包含 jQuery UI 来改进。
- 几乎可以肯定它可以做成一个插件,看起来不那么难看。
- 需要一个大而实用但不美观的
if/else if 语句。
- 需要至少传递一次
each() 才能分配 div 元素的“默认”/“自然”高度。
- 如果
divs 不是position: absolute,它们会缩小到内联元素的基线(因为它们是display: inline-block),如果它们是float: left,这可能不是问题(显然是 float: right)。
希望它有用,但在当前状态下肯定不理想。
编辑以发布上述的插件化版本(它保留了与以前相同的所有问题):
(function($) {
$.fn.slideTo = function(slideToMin, duration, easing) {
var slideToMin = slideToMin || 30,
duration = duration || 500,
easing = easing || 'linear';
$(this)
.attr('data-height', $(this).height())
.click(
function() {
var curH = $(this).height();
if ($(this).is(':animated')) {
return false;
}
else if (curH == $(this).attr('data-height')) {
$(this).animate({
'height': slideToMin
}, duration, easing);
}
else if (curH == slideToMin) {
$(this).animate({
'height': $(this).attr('data-height')
}, duration, easing);
}
});
return $(this);
};
})(jQuery);
$('.toggles').slideTo(50,1500,'swing');
JS Fiddle demo.
- slideToMin:这可以是或者一个带引号的字符串,例如'3em'、'20px',或者一个不带引号的数字,例如
30,它代表你想要的高度要滑动到的元素。如果没有提供单位,则默认情况下高度以像素为单位。
- duration:动画持续的毫秒数。
- easing:
一个带引号的字符串,定义动画中使用的缓动类型;如果没有 jQuery UI,这是“线性”或“摆动”。 使用 jQuery UI 其他选项可能是可能的,但这是未经测试的。如果未指定,则动画默认为“线性”。 因为在带引号的字符串中使用单位会导致最终的 else if 返回 false(显然,我想...叹息),请为此仅使用不带引号的数字参数变量(或编辑插件以正确处理带单位的引号字符串...)。
直到我发布这个我才意识到的一个更大的问题是插件版本只允许动画的一个迭代。我对此感到困惑,尽管对其他人来说可能很明显?
好的,这似乎是if 语句中的高度评估。使用 3em 导致最终的 else if : curH == toggleMinHeight 返回 false。大概是由于该变量中存在单位(em)。对上述指南进行了编辑,以反映不应使用单位。
参考资料: