代码之家  ›  专栏  ›  技术社区  ›  Greg

如何使用jQuery[duplicate]将元素设置为其自然高度的动画

  •  16
  • Greg  · 技术社区  · 15 年前

    我试图让一个元素动画化到它的“自然”高度,也就是说,如果它有 height: auto;

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

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

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

    <!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>
    
    9 回复  |  直到 15 年前
        1
  •  11
  •   aaaaaa    14 年前

    我允许自己回答这个问题,即使很久以前就有人回答了,因为这对我很有帮助。

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

    看看我所做的,它非常有效:

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

    我写得很快,希望将来能对别人有所帮助。

        2
  •  10
  •   Tobias    13 年前

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

        3
  •  7
  •   Sampson    15 年前

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

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

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

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

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

        4
  •  1
  •   Geoffrey Booth    14 年前

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

    我在这篇文章中尝试了许多解决方案,其中一个对我有效的是乔纳森·桑普森提出的涉及克隆元素的“黑客建议”。我把他的想法翻译成以下代码。请随时提出改进建议。

    这些函数被委托给父元素来处理通过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
  •  1
  •   Dinis Correia    13 年前

    只是在animate函数中添加了一个回调函数,以便在动画结束时将元素的高度设置为“auto”(在我的例子中,该特定元素的内容可能会更改并变大)。

        6
  •  0
  •   Steerpike    15 年前
    $('div').click(function() { 
        if($('p').is(':hidden')) {
           $('p').slideUp();
        } else {
           $('p').slideDown(function() { $('p').css('height','1px'); });
        }
    }
    

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

        7
  •  0
  •   Andy Richdale    13 年前

    这对我有用。

    <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
  •  0
  •   mmmeff    10 年前

    我的解决方案是将其存储在 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
  •  0
  •   Community ahmed    7 年前

    this answer ,建议使用animate()函数将高度设置为“show”。我必须编辑我的“slideUp”风格的动画以使用高度:“隐藏”来处理它。