2009-09-02 75 views
16

我試圖讓元素動畫到其「自然」高度 - 即如果它具有height: auto;,那麼它的高度就是它的高度。我如何使用jQuery將元素動畫化爲其自然高度

我想出這個:

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> 
+0

不要忘記VAR的$此變量格雷格 – redsquare 2009-09-02 20:04:12

回答

6

我可以建議一個同樣-hackish的解決方案...克隆的元素,其定位出來的觀點,並得到其高度......然後將其刪除和動畫原件。

這且不說,你也可以使用$ .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上應用slidingUp/Down。

+0

聽起來像它會工作,但我不知道這將是一個進步:)我有什麼工作,但我是新來的jQuery所以我想一定有一個非hacky的方式 – Greg 2009-09-02 19:49:58

+2

你決定不去使用$ .slideUp()和$ .slideDown()? – Sampson 2009-09-02 19:53:51

+0

我需要它停在1px的高度,我認爲這些功能不可能(儘管可能是錯誤的) – Greg 2009-09-02 19:56:25

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

這應該將p標籤的高度設置爲1px,一旦它們完成滑動。

+0

這會將每個p-tag的高度設置爲1px。 – Sampson 2009-09-02 20:07:24

+0

$(this).css('height','1px');應該沒事的話。 – Steerpike 2009-09-02 20:10:22

+0

您正在將其應用於slideDown()方法的回調函數中,這意味着只要它可見,就會再次隱藏起來。你的意思是把它設置爲幻燈片嗎? – Sampson 2009-09-02 20:16:01

11

我允許自己回答這個問題,即使很久以前已經回答了,因爲它只是幫助了我。

事實上,我不明白第一個答案:爲什麼打開一個半封閉的元素來獲得它的高度,然後再關閉它?

開始的時候,你隱藏了這個元素,只是它的一部分出現了吧?最好的方式(我相信)做到這一點,已與JavaScript。因此,當您隱藏元素時,只需將原始高度保存在一個var中,這樣就不必隱藏(onready)-show-save高度隱藏以便切換元素的可見性。

看我做什麼,它完美的作品:

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

在這裏,當你打電話給你切換功能,你知道什麼是你原來的元素高度不手淫左右。

我寫得很快,希望能在未來幫助別人。

+0

這是一個更好的答案。謝謝。 – theorise 2012-08-02 10:17:56

1

如果可能的話,我還想在這個舊線程中加入聲音,以防我的解決方案幫助任何人。我的具體情況是這樣的:我有一些div被設置爲最大高度值,將它們限制爲三行高,並且當用戶將它們鼠標懸停時,我希望它們擴展到它們的自然高度;當鼠標光標離開div時,我希望它們縮小到最大三行高度。我需要使用CSS max-height屬性,而不是高度,因爲我有一些div只包含一行或兩行文本,我不希望它們不必要地高。

我在這個主題中嘗試了很多解決方案,而對我而言的解決方案是Jonathan Sampson提出的涉及克隆元素的'hackish建議'。我將他的想法轉化爲下面的代碼。請隨時提出改進建議。

的職能委託給處理DIV的通過Ajax調用創建的父元素。該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'); 
}); 
1

發現這個職位,並最終使用格雷格的原1px的建議 - 偉大工程!

只是增加了一個回調的動畫功能,元素的高度設置爲「自動」時,動畫結束(在我的情況下,特定元素的含量可以改變和更大)。

10

我發現是簡單地與在高度的限制和設置爲溢出一個div包裹內容元素的最簡單的解決方案:隱藏。這將內部內容元素截斷爲包裝div的高度。當用戶單擊,懸停等顯示內容元素的全部高度時 - 只需將包裝div設置爲內部內容div的高度即可。

+0

我喜歡這個解決方案,非常乾淨,靈活,並且是一種避免必須根據內容進行一些js計算的絕佳方法。頂級真棒托比亞斯! – 2016-06-13 15:44:10

0

這對我有效。

<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> 
0

我的解決辦法是在關閉按鈕容器的原始尺寸的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; 
} 
0

我想指出this answer,這表明設置高度「秀」與動畫()函數。我必須編輯我的「slideUp」樣式以使用height:「hide」來處理它。

相關問題