如何使用jQuery将元素动画化为其自然高度

我试图让一个元素动画到它的“自然”高度 – 即它有height: auto;

我想出了这个:

 var currentHeight = $this.height(); $this.css('height', 'auto'); var height = $this.height(); $this.css('height', currentHeight + 'px'); $this.animate({'height': height}); 

有一个更好的方法吗? 这感觉有点像黑客。

编辑:这是一个完整的脚本,可供想要测试的任何人使用。

    jQuery  p { overflow: hidden; background-color: red; border: 1px solid black; } .closed { height: 1px; }    $().ready(function() { $('div').click(function() { $('p').each(function() { var $this = $(this); if ($this.hasClass('closed')) { var currentHeight = $this.height(); $this.css('height', 'auto'); var height = $this.height(); $this.css('height', currentHeight + 'px'); $this.animate({'height': height}); } else { $this.animate({'height': 1}); } $this.toggleClass('closed'); }); }); });    
Click Me

Hello - I started open

Hello - I started closed

我可以建议一个同样hackish的解决方案…克隆元素,将其置于视图之外,并获得其高度…然后删除它并为原始动画制作动画。

除此之外,您还可以使用$ .slideUp()和$ .slideDown():

 $this.hasClass('closed') ? $(this).slideDown() : $(this).slideUp() ; 

如果需要保留1px行,可以将其应用于父元素:

 
Hello World

并在.toggleMe div上应用slidingUp / Down。

我允许自己回答这个问题,即使很久以前它已被回答,因为它只是帮助了我。

事实上,我不明白第一个答案:为什么打开一个半封闭的元素来获得它的高度,然后再次关闭它?

在开始时,您隐藏元素,以便只显示其中的一部分,对吧? 使用javascript,最好的方式(我相信)是这样做的。 因此,当您隐藏元素时,只需将orig高度保存在var中,这样您就不必隐藏(onready)-show-save height-hide以便能够切换元素可见性。

看看我做了什么,它完美地运作:

 $(document).ready(function(){ var origHeight = $("#foo").css('height'); $("#foo").css({"height" : "80px"}); $("#foo .toggle").bind("click", function(event){ toggleFoo(event, lastSearchesMidHeight); }); }); 

在这里,当您调用切换function时,您知道原始元素高度是多少而不需要四处寻找。

我写得很快,希望它能帮助将来的某个人。

我找到的最简单的解决方案是简单地用一个高度有限的div包装内容元素并设置为overflow:hidden。 这会将内部内容元素截断为包装div的高度。 当用户点击,hover等以显示内容元素的完整高度时 – 简单地将包装div设置为内部内容div的高度。

如果可以的话,我也想加入这个旧线程,万一我的解决方案可以帮助任何人。 我的具体情况是这样的:我有一些设置了最大高度值的div,它们将它们限制为三行高,当用户将鼠标移过它们时,我希望它们扩展到它们的自然高度; 当鼠标光标离开div时,我希望它们缩回到剪切的最大三行高。 我需要使用CSS max-height属性,而不是高度,因为我有一些div只包含一行或两行文本,我不希望它们不必要地高。

我在这个post中尝试了很多解决方案,而对我有用的那个解决方案是由Jonathan Sampson建议的涉及克隆元素的“hackish建议”。 我将他的想法翻译成以下代码。 请随时提出改进建议。

这些函数被委托给父元素来处理通过Ajax调用创建的div。 div.overflow_expandable类具有以下声明: { max-height: 5em; overflow: hidden; } { max-height: 5em; overflow: hidden; }

 $('#results').delegate('div.overflow_expandable', 'mouseenter', function() { var $this = $(this); // Close any other open divs $('#results div.overflow_expandable').not($(this)).trigger('mouseleave'); // We need to convert the div's current natural height (which is less than // or equal to its CSS max-height) to be a defined CSS 'height' property, // which can then animate; and we unset max-height so that it doesn't // prevent the div from growing taller. if (!$this.data('originalHeight')) { $this.data('originalHeight', $this.height()); $this.data('originalMaxHeight', parseInt($this.css('max-height'))); $this.css({ 'max-height':'none', height: $this.data('originalHeight') }); } // Now slide out if the div is at its original height // (ie in 'closed' state) and if its original height was equal to // its original 'max-height' (so when closed, it had overflow clipped) if ($this.height() == $this.data('originalHeight') && $this.data('originalMaxHeight') == $this.data('originalHeight')) { // To figure out the new height, clone the original element and set // its height to auto, then measure the cloned element's new height; // then animate our div to that height var $clone = $this.clone().css({ height: 'auto', position: 'absolute', zIndex: '-9999', left: '-9999px', width: $this.width() }) .appendTo($this); $this.animate({ height: $clone.height() }, 'slow'); $clone.detach(); } }).delegate('div.overflow_expandable', 'mouseleave', function() { var $this = $(this); // If the div has 'originalHeight' defined (it's been opened before) and // if it's current height is greater than 'originalHeight' (it's open // now), slide it back to its original height if ($this.data('originalHeight') && $this.height() > $this.data('originalHeight')) $this.animate({ height: $this.data('originalHeight') }, 'slow'); }); 

发现这篇文章并最终使用Greg的原始1px建议 – 效果很好!

刚刚添加了一个回调动画函数,在动画结束时将元素的高度设置为’auto’(在我的情况下,该特定元素的内容可能会更改并且更大)。

 $('div').click(function() { if($('p').is(':hidden')) { $('p').slideUp(); } else { $('p').slideDown(function() { $('p').css('height','1px'); }); } } 

这应该在完成滑动后将p标签的高度设置为1px。

这对我有用。

 
Cars

我的解决方案是在关闭按钮的data属性中存储容器的原始大小(如果你不使用相同的按钮再次显示容器,也可以存储在容器本身中):

 $(document).ready(function(){ $('.infoBox .closeBtn').toggle(hideBox, showBox); }); function hideBox() { var parent = $(this).parent(); $(this).text('Show').data('originalHeight', parent.css('height')); parent.animate({'height': 20}); return false; } function showBox() { var parent = $(this).parent(); $(this).text('Hide'); parent.animate({ 'height': $(this).data('originalHeight') }); return false; } 

我想指出这个答案 ,建议使用animate()函数将高度设置为“show”。 我必须编辑我的“slideUp”样式动画以使用高度:“隐藏”以使用它。