如何使用 jQuery 将元素动画到其自然高度 [重复]

Posted

技术标签:

【中文标题】如何使用 jQuery 将元素动画到其自然高度 [重复]【英文标题】:How can I Animate an Element to its natural height using jQuery [duplicate] 【发布时间】:2010-11-25 01:52:34 【问题描述】:

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

我想出了这个:

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

$this.animate('height': height);

有没有更好的方法来做到这一点?感觉有点像 hack。

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

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html lang="en"> 
    <head>
        <title>jQuery</title>
        <style type="text/css">
            p  overflow: hidden; background-color: red; border: 1px solid black; 
            .closed  height: 1px; 
        </style>
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.js"></script>
        <script type="text/javascript">
        $().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');
                );
            );
        );
        </script>
    </head>

    <body>

        <div>Click Me</div>
        <p>Hello - I started open</p>
        <p class="closed">Hello - I started closed</p>

    </body>
</html>

【问题讨论】:

别忘了修改 $this 变量 Greg 【参考方案1】:

我允许自己回答这个帖子,即使它很久以前就已经回答过了,因为它只是帮助了我。

其实第一个答案我没看懂:为什么要打开一个半封闭的元素来获取它的高度,然后再关闭它?

一开始,你隐藏了元素,只显示了它的一部分,对吧?最好的方法(我相信)是使用 javascript 做好准备。因此,当您隐藏元素 onready 时,只需将 orig 高度保存在 var 中,这样您就不必使用 hide(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); );
);

在这里,当你调用你的切换函数时,你知道你的原始元素高度是多少,而无需左右晃动。

我写得很快,希望它可以帮助将来的人。

【讨论】:

这是一个更好的答案。谢谢。【参考方案2】:

我找到的最简单的解决方案是简单地用一个高度有限的 div 包装内容元素并设置为溢出:隐藏。这会将内部内容元素截断为包装 div 的高度。当用户单击、悬停等以显示内容元素的完整高度时 - 只需将包装 div 设置为内部内容 div 的高度即可。

【讨论】:

我喜欢这个解决方案,它非常干净、灵活,并且是避免进行一些可能因内容而中断的 js 计算的绝佳方式。最棒的托拜厄斯!!【参考方案3】:

我可以建议一个同样骇人听闻的解决方案...克隆该元素,将其放置在视野之外,并获取其高度...然后将其删除并为您的原始元素设置动画。

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

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

如果您需要保留 1px 的线,您可以将其与父元素一起应用:

<div style='border-top:1px solid #333333'>
  <div class='toggleMe'>Hello World</div>
</div>

并在 .toggleMe div 上应用上滑/下滑。

【讨论】:

听起来它可以工作,但我不确定它是否会有所改进:) 我有什么工作但我是 jQuery 新手,所以我认为必须有一种非 hacky 方式 您决定不使用 $.slideUp() 和 $.slideDown() 的任何原因? 我需要它停止在 1px 高度,我认为这些功能不可能(虽然可能是错误的) 如果这很重要的话,它还需要能够在 jQuery 开始运行之前以关闭或打开状态启动 1px 的高度可以通过切换元素周围的元素来模拟吗? ?【参考方案4】:

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

我尝试了此线程中的许多解决方案,其中一个对我有用的是 Jonathan Sampson 提出的涉及克隆元素的“hackish 建议”。我将他的想法翻译成下面的代码。请随时提出改进建议。

这些函数被委托给父元素来处理通过 Ajax 调用创建的 div。 div.overflow_expandable 类具有以下声明: 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 
    // (i.e. 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');
);

【讨论】:

【参考方案5】:

找到这篇文章并最终使用 Greg 最初的 1px 建议 - 效果很好!

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

【讨论】:

【参考方案6】:
$('div').click(function()  
    if($('p').is(':hidden')) 
       $('p').slideUp();
     else 
       $('p').slideDown(function()  $('p').css('height','1px'); );
    

一旦它们完成滑动,应该将 p 标签的高度设置为 1px。

【讨论】:

这会将每个 p-tag 的高度设置为 1px。 $(this).css('height','1px');那应该没问题。 您将它应用在 slideDown() 方法的回调中,这意味着一旦它可见,它将再次被隐藏。您的意思是为上滑设置它吗? 嗯,我想我的显示/隐藏功能搞混了,是的。无论哪种方式,让显示/隐藏功能工作都应该比检查高度等简单得多。【参考方案7】:

这对我有用。

<div class="product-category">
    <div class="category-name">
        Cars
    </div>
    <div class="category-products" style="display: none; overflow: hidden;">
        <div class="product">Red Car</div>
        <div class="product">Green Car</div>
        <div class="product">Yellow Car</div>
    </div>
</div>

<script type="text/javascript">
$(document).ready(function() 
    $('.product-category .category-name').click(function() 
        if ($(this).parent().hasClass('active')) 
            $(this).parent().removeClass('active');
            var height = $(this).parent().find('.category-products').height();
            $(this).parent().find('.category-products').animate( height : '0px' , 600, function() 
                $(this).parent().find('.category-products').height(height).hide();
            );
         else 
            $(this).parent().addClass('active');
            var height = $(this).parent().find('.category-products').height();
            $(this).parent().find('.category-products').height(0).show().animate( height : height + 'px' , 600);
        
    );
);
</script>

【讨论】:

【参考方案8】:

我的解决方案是在关闭按钮的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;

【讨论】:

【参考方案9】:

我想指向this answer,它建议使用 animate() 函数将高度设置为“显示”。我必须编辑我的“slideUp”样式动画以使用 height:"hide" 来使用它。

【讨论】:

以上是关于如何使用 jQuery 将元素动画到其自然高度 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

jQuery动画高度和溢出

jQuery - 动画高度自动

jQuery.animate() 函数详解

jQuery-4.动画篇---上卷下拉效果

jQuery:动画宽度/高度,但保持居中

jQuery:如何在没有已知高度的情况下动画高度变化?