jQueryを使用して要素を自動高さにアニメーション化する


171

<div>from 200pxからautoheight までアニメートしたい。私はそれを動作させることができないようです。誰か知っていますか?

これがコードです:

$("div:first").click(function(){
  $("#first").animate({
    height: "auto"
  }, 1000 );
});

14
最良の回答を承認済みとしてマークする必要があります。
kleinfreund 2014年


@IanMackinnonこの質問は確かにより良い答えを持っています。この質問の重複として、その質問を閉じました。
マダラのゴースト

回答:


254
  1. 現在の高さを保存します。

    var curHeight = $('#first').height();
  2. 高さを一時的に自動に切り替えます。

    $('#first').css('height', 'auto');
  3. 自動高さを取得します。

    var autoHeight = $('#first').height();
  4. に切り替えてcurHeightアニメーション化しautoHeightます。

    $('#first').height(curHeight).animate({height: autoHeight}, 1000);

そして一緒に:

var el = $('#first'),
    curHeight = el.height(),
    autoHeight = el.css('height', 'auto').height();
el.height(curHeight).animate({height: autoHeight}, 1000);

@ダニエル、あなたのJSコードはどこですか?そのビットと、参照する要素を示すHTMLの一部を投稿します。
David Tang

21
これは機能しますが、要素に自動.animated({height: autoHeight}, 1000, function(){ el.height('auto'); });
拡張

レスポンシブデザインで固定の高さを設定する場合は注意が必要です。ユーザーが画面のサイズを変更すると、混乱します。アニメーションが完了したら、高さを「自動」に設定することをお勧めします。
Jonathan Tonge 2014年

4
これはFOUCを引き起こす可能性があります。ユーザーは、アニメーション化する前に、要素が一瞬完全な高さにジャンプするのを見るかもしれません。
成分14

1
要素opacity: 0; position: absolute;を測定中に最初に指定し、完了したらそれらを削除することで、FOUC(「スタイルのないコンテンツのフラッシュ」)を防ぐことができます。
JacobEvelyn

194

IMOこれは最もクリーンで簡単なソリューションです。

$("#first").animate({height: $("#first").get(0).scrollHeight}, 1000 );

説明:DOMは、最初のレンダリングから、自動高さに設定されたときの拡張divのサイズをすでに認識しています。このプロパティは、DOMノードにとして格納されますscrollHeight。呼び出してjQuery要素からDOM要素をフェッチするだけでget(0)、プロパティにアクセスできます。

高さをautoに設定するコールバック関数を追加すると、アニメーションが完了した後の応答性が向上します(クレジットchris-williams)。

$('#first').animate({
    height: $('#first').get(0).scrollHeight
}, 1000, function(){
    $(this).height('auto');
});

2
すごい!developer.mozilla.org/en-US/docs/Web/API/Element.scrollHeightによると、IE8ではサポートされclientHeightているようですが、サポートされていないようです:developer.mozilla.org/en-US/docs/Web/ API / Element.clientHeight
Sven

1
マージンは、ボックスモデルの定義によると、オブジェクトの高さの一部ではありません。ただし、いつでも自分でマージンを追加できます。
2015年

22
それは任意のちらつきなしで最適に動作し、本当によく仕事をしていませんので、これは受け入れ答えなければなりません
Einius

7
これも最良の解決策だと思います。応答性を高めるために高さをautoに設定するコールバック関数を追加します。 $('#first').animate({ height: $('#first').get(0).scrollHeight }, 1000, function() { $(this).height('auto'); });
クリスウィリアムズ

1
うわー、これは超エレガントです。それはまたで動作scrollWidth幅アニメーションのために。
2015年

24

これは、基本的にはBox9の回答と同じアプローチですが、通常のanimateと同じ引数取る素敵なjqueryプラグインにラップしました。これは、アニメーション化されたパラメーターがさらに必要になり、同じコードを何度も繰り返すのに飽き飽きするためです。 :

;(function($)
{
  $.fn.animateToAutoHeight = function(){
  var curHeight = this.css('height'),
      height = this.css('height','auto').height(),
      duration = 200,
      easing = 'swing',
      callback = $.noop,
      parameters = { height: height };
  this.css('height', curHeight);
  for (var i in arguments) {
    switch (typeof arguments[i]) {
      case 'object':
        parameters = arguments[i];
        parameters.height = height;
        break;
      case 'string':
        if (arguments[i] == 'slow' || arguments[i] == 'fast') duration = arguments[i];
        else easing = arguments[i];
        break;
      case 'number': duration = arguments[i]; break;
      case 'function': callback = arguments[i]; break;
    }
  }
  this.animate(parameters, duration, easing, function() {
    $(this).css('height', 'auto');
    callback.call(this, arguments);
  });
  return this;
  }
})(jQuery);

編集:チェーン可能でよりクリーンになりました


23

より良いソリューションは、要素の高さを設定するためにJSに依存しません。以下は、固定の高さ要素を完全な(「自動」)高さにアニメーション化するソリューションです。

var $selector = $('div');
    $selector
        .data('oHeight',$selector.height())
        .css('height','auto')
        .data('nHeight',$selector.height())
        .height($selector.data('oHeight'))
        .animate({height: $selector.data('nHeight')},400);

https://gist.github.com/2023150


2
このonelinerは理解するのが容易ではありません。おそらく、いくつかの行を書くと、他の人が少し良くなるのを助けるでしょう。
Jaap

ユーザーがウィンドウサイズを調整すると自動高さが変わる可能性があるため、これが最良のソリューションです。以下を参照してください://フィルター関数の高さをアニメーション化toggleSlider(){if($( '#filters')。height()!= 0){$( '#filters')。animate({height: '0 '}); } else {var $ selector = $( '#filters'); $ selector .data( 'oHeight'、$ selector.height()).css( 'height'、 'auto').data( 'nHeight'、$ selector.height()).height($ selector.data( ' oHeight ')).animate({height:$ selector.data(' nHeight ')}、400); }; console.log( 'agg'); }
リッキー

divを開くように機能しますが、400ミリ秒以上アニメーション化しません。たぶん、別の設定をしているのかもしれませんが、それはすぐに開きます。
ntgCleaner 2016年

機能しますが、これはheight固定値(122pxなど)に設定されます。私の要素はしばらくして高さが変わったので、duration引数(400)をオプションに{duration: 400, complete: function() {$selector.css('height', 'auto');}}
置き換える必要

12

これは機能しており、以前のソリューションよりも簡単です:

CSS:

#container{
  height:143px;  
}

.max{
  height: auto;
  min-height: 143px;
}

JS:

$(document).ready(function() {
    $("#container").click(function() {      
        if($(this).hasClass("max")) {
            $(this).removeClass("max");
        } else {
            $(this).addClass("max");
        }

    })
});

注:このソリューションにはjQuery UIが必要です


1
元の質問はjqueryのみに関するものでしたが、これにはJquery UIプラグインが必要であることを言及する必要があります。ただし、Jquery UIを使用している場合は機能します。
user56reinstatemonica8

4
$(this).toggleClass( 'max'、250);を使用することもできます。ifステートメントを使用する代わりに
Antoine Hedgecock 2014年

1
.addClassandに2番目の値を含めるのはなぜ.removeClassですか?
Bowl0stu


7

いつでも#firstの子要素をラップして、ラッパーの高さを変数として保存できます。これは最もかわいらしい、または最も効率的な答えではないかもしれませんが、トリックを行います。

リセットを組み込んだフィドルです。

しかし、あなたの目的のために、ここに肉とジャガイモがあります:

$(function(){
//wrap everything inside #first
$('#first').children().wrapAll('<div class="wrapper"></div>');
//get the height of the wrapper 
var expandedHeight = $('.wrapper').height();
//get the height of first (set to 200px however you choose)
var collapsedHeight = $('#first').height();
//when you click the element of your choice (a button in my case) #first will animate to height auto
$('button').click(function(){
    $("#first").animate({
        height: expandedHeight            
    })
});
});​


5

私はなんとかそれを修正しました:Dがコードを示します。

var divh = document.getElementById('first').offsetHeight;
$("#first").css('height', '100px');
$("div:first").click(function() {
  $("#first").animate({
    height: divh
  }, 1000);
});

4

高さを自動に戻すコールバックを追加することで、ウィンドウサイズの変更に応答してLiquinautの応答を作成できます。

$("#first").animate({height: $("#first").get(0).scrollHeight}, 1000, function() {$("#first").css({height: "auto"});});

4

基本的に高さautoは、要素がレンダリングされた後でのみ使用できます。固定の高さを設定した場合、または要素が表示されない場合は、トリックなしではアクセスできません。

幸いにも、使用できるいくつかのトリックがあります。

要素のクローンを作成し、ビューの外側に表示して高さを自動にします。クローンから要素を取り出し、後でメイン要素に使用できます。私はこの機能を使用しており、うまく機能しているようです。

jQuery.fn.animateAuto = function(prop, speed, callback){
    var elem, height, width;

    return this.each(function(i, el){
        el = jQuery(el), elem =    el.clone().css({"height":"auto","width":"auto"}).appendTo("body");
        height = elem.css("height"),
        width = elem.css("width"),
        elem.remove();

        if(prop === "height")
            el.animate({"height":height}, speed, callback);
        else if(prop === "width")
            el.animate({"width":width}, speed, callback);  
        else if(prop === "both")
            el.animate({"width":width,"height":height}, speed, callback);
    });   
}

使用法:

$(".animateHeight").bind("click", function(e){
    $(".test").animateAuto("height", 1000); 
});

$(".animateWidth").bind("click", function(e){
    $(".test").animateAuto("width", 1000);  
});

$(".animateBoth").bind("click", function(e){
    $(".test").animateAuto("both", 1000); 
});

1
その関数を使用したくない場合は、次のようにします。var clone = element.clone()clone.appendTo( 'body')clone.css( 'height'、 'auto')var itemHeight = clone.outerHeight( ); clone.remove()でitemHeight変数にアイテムの高さが設定されたので、アニメーションだけでなくそれ以外にも使用できます。
スタンジョージ

3

あなたはいつでもこれを行うことができます:

jQuery.fn.animateAuto = function(prop, speed, callback){
var elem, height, width;
return this.each(function(i, el){
    el = jQuery(el), elem = el.clone().css({"height":"auto","width":"auto"}).appendTo("body");
    height = elem.css("height"),
    width = elem.css("width"),
    elem.remove();

    if(prop === "height")
        el.animate({"height":height}, speed, callback);
    else if(prop === "width")
        el.animate({"width":width}, speed, callback);  
    else if(prop === "both")
        el.animate({"width":width,"height":height}, speed, callback);
});  
}

ここにフィドルがあります:http : //jsfiddle.net/Zuriel/faE9w/2/


1
あなたは置き換えることができます:.appendTo("body")by.appendTo(el.parent())
Steffi 14

2

セレクターが一致していないようです。要素のIDは「first」ですか、それともすべてのdivの最初の要素ですか?

より安全な解決策は「これ」を使用することです:

// assuming the div you want to animate has an ID of first
$('#first').click(function() {
  $(this).animate({ height : 'auto' }, 1000);
});

1
ああ。さて、あなたは解決策を発見したようです。安全のため、$(this)クリックハンドラー内では引き続き使用します。
EMMERICH、2011

10
animate({height: 'auto'})効果はありません。少なくとも、jQuery 1.6.4ではできません。
ジャニスElmeris

2

これを試してください、

var height;
$(document).ready(function(){
    $('#first').css('height','auto');
    height = $('#first').height();
    $('#first').css('height','200px');
})

 $("div:first").click(function(){
  $("#first").animate({
    height: height
  }, 1000 );
});

これは機能しません。varの高さは、ready関数内でアクセスできます。
meo

レディ関数の前に高さを定義し、varの高さよりも高さのみを使用します。このようにすると、ダニエルが機能する可能性があります
Prakash

2

これがBORDER-BOXで動作するものです...

こんにちは、みんな。これは私が同じことをするために書いたjQueryプラグインですが、にbox-sizing設定したときに発生する高さの違いも考慮に入れていますborder-box

また、要素をy軸に沿って縮小して非表示にする「yShrinkOut」プラグインも含めました。


// -------------------------------------------------------------------
// Function to show an object by allowing it to grow to the given height value.
// -------------------------------------------------------------------
$.fn.yGrowIn = function (growTo, duration, whenComplete) {

    var f = whenComplete || function () { }, // default function is empty
        obj = this,
        h = growTo || 'calc', // default is to calculate height
        bbox = (obj.css('box-sizing') == 'border-box'), // check box-sizing
        d = duration || 200; // default duration is 200 ms

    obj.css('height', '0px').removeClass('hidden invisible');
    var padTop = 0 + parseInt(getComputedStyle(obj[0], null).paddingTop), // get the starting padding-top
        padBottom = 0 + parseInt(getComputedStyle(obj[0], null).paddingBottom), // get the starting padding-bottom
        padLeft = 0 + parseInt(getComputedStyle(obj[0], null).paddingLeft), // get the starting padding-left
        padRight = 0 + parseInt(getComputedStyle(obj[0], null).paddingRight); // get the starting padding-right
    obj.css('padding-top', '0px').css('padding-bottom', '0px'); // Set the padding to 0;

    // If no height was given, then calculate what the height should be.
    if(h=='calc'){ 
        var p = obj.css('position'); // get the starting object "position" style. 
        obj.css('opacity', '0'); // Set the opacity to 0 so the next actions aren't seen.
        var cssW = obj.css('width') || 'auto'; // get the CSS width if it exists.
        var w = parseInt(getComputedStyle(obj[0], null).width || 0) // calculate the computed inner-width with regard to box-sizing.
            + (!bbox ? parseInt((getComputedStyle(obj[0], null).borderRightWidth || 0)) : 0) // remove these values if using border-box.
            + (!bbox ? parseInt((getComputedStyle(obj[0], null).borderLeftWidth || 0)) : 0) // remove these values if using border-box.
            + (!bbox ? (padLeft + padRight) : 0); // remove these values if using border-box.
        obj.css('position', 'fixed'); // remove the object from the flow of the document.
        obj.css('width', w); // make sure the width remains the same. This prevents content from throwing off the height.
        obj.css('height', 'auto'); // set the height to auto for calculation.
        h = parseInt(0); // calculate the auto-height
        h += obj[0].clientHeight // calculate the computed height with regard to box-sizing.
            + (bbox ? parseInt((getComputedStyle(obj[0], null).borderTopWidth || 0)) : 0) // add these values if using border-box.
            + (bbox ? parseInt((getComputedStyle(obj[0], null).borderBottomWidth || 0)) : 0) // add these values if using border-box.
            + (bbox ? (padTop + padBottom) : 0); // add these values if using border-box.
        obj.css('height', '0px').css('position', p).css('opacity','1'); // reset the height, position, and opacity.
    };

    // animate the box. 
    //  Note: the actual duration of the animation will change depending on the box-sizing.
    //      e.g., the duration will be shorter when using padding and borders in box-sizing because
    //      the animation thread is growing (or shrinking) all three components simultaneously.
    //      This can be avoided by retrieving the calculated "duration per pixel" based on the box-sizing type,
    //      but it really isn't worth the effort.
    obj.animate({ 'height': h, 'padding-top': padTop, 'padding-bottom': padBottom }, d, 'linear', (f)());
};

// -------------------------------------------------------------------
// Function to hide an object by shrinking its height to zero.
// -------------------------------------------------------------------
$.fn.yShrinkOut = function (d,whenComplete) {
    var f = whenComplete || function () { },
        obj = this,
        padTop = 0 + parseInt(getComputedStyle(obj[0], null).paddingTop),
        padBottom = 0 + parseInt(getComputedStyle(obj[0], null).paddingBottom),
        begHeight = 0 + parseInt(obj.css('height'));

    obj.animate({ 'height': '0px', 'padding-top': 0, 'padding-bottom': 0 }, d, 'linear', function () {
            obj.addClass('hidden')
                .css('height', 0)
                .css('padding-top', padTop)
                .css('padding-bottom', padBottom);
            (f)();
        });
};

デフォルト値を受け入れるために、私が使用したすべてのパラメーターを省略したり、nullに設定したりできます。私が使用したパラメータ:

  • growTo:すべての計算をオーバーライドして、オブジェクトが成長するCSSの高さを設定する場合は、このパラメーターを使用します。
  • 期間:アニメーションの期間(明らかに)。
  • whenComplete:アニメーションが完了したときに実行される関数。

2

スライドを切り替えるBox9の回答を展開)

$("#click-me").click(function() {
  var el = $('#first'),
  curHeight = el.height(),
  autoHeight = el.css('height', 'auto').height(),
  finHeight = $('#first').data('click') == 1 ? "20px" : autoHeight;
  $('#first').data('click', $(this).data('click') == 1 ? false : true);
  el.height(curHeight).animate({height: finHeight});
});
#first {width: 100%;height: 20px;overflow:hidden;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="first">
  <div id="click-me">Lorem ipsum dolor sit amet, consectetur adipiscing elit</div>
  Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit,
</div>


1

このスレッドが古いにもかかわらず、私はこの回答を投稿しています。受け入れられた答えが私のために働くために得ることができませんでした。これはうまく機能し、非常に単純です。

必要な各divの高さをデータにロードします

$('div').each(function(){
    $(this).data('height',$(this).css('height'));
    $(this).css('height','20px');
});

次に、クリックでアニメーション化するときにそれを使用します。

$('div').click(function(){
    $(this).css('height',$(this).data('height'));
});

私はCSSトランジションを使用しているため、jQuery animateは使用していませんが、同じようにアニメーション化できます。


1

データ属性に保存できます。

$('.colapsable').each(function(){
    $(this).attr('data-oheight',$(this).height());
    $(this).height(100);
});

$('.colapsable h2:first-child').click(function(){
    $(this).parent('.colapsable').animate({
            height: $(this).parent('.colapsible').data('oheight')
        },500);
    }
});

本質的にはヘットラーのワンライナーと同じですが、理解しやすいです。
Timothy Groote、2015

1

私は、同じ問題に遭遇したWordpressショートコードにこれを実装する1ページの複数の読み取り領域にこの機能が必要でした。

技術的には、ページ上のすべての読み取りスパンの高さが固定されています。そして、それらをトグルで自動高さに個別に拡張できるようにしたかったのです。最初のクリック:「テキストスパンの高さ全体に拡張」、2回目のクリック:「デフォルトの高さ70ピクセルに折りたたむ」

HTML

 <span class="read-more" data-base="70" data-height="null">
     /* Lots of text determining the height of this span */
 </span>
 <button data-target='read-more'>Read more</button>

CSS

span.read-more {
    position:relative;
    display:block;
    overflow:hidden;
}

したがって、これは非常に単純に見えdata-baseますが、必要な固定高さを設定するために必要な属性です。data-height属性は、Iは、要素の実際の(動的な)高さを格納するために使用されます。

jQueryの部分

jQuery(document).ready(function($){

  $.fn.clickToggle = function(func1, func2) {
      var funcs = [func1, func2];
      this.data('toggleclicked', 0);
      this.click(function() {
          var data = $(this).data();
          var tc = data.toggleclicked;
          $.proxy(funcs[tc], this)();
          data.toggleclicked = (tc + 1) % 2;
      });
      return this;
  };

    function setAttr_height(key) {
        $(key).each(function(){
            var setNormalHeight = $(this).height();
            $(this).attr('data-height', setNormalHeight);
            $(this).css('height', $(this).attr('data-base') + 'px' );
        });
    }
    setAttr_height('.read-more');

    $('[data-target]').clickToggle(function(){
        $(this).prev().animate({height: $(this).prev().attr('data-height')}, 200);
    }, function(){
        $(this).prev().animate({height: $(this).prev().attr('data-base')}, 200);
    });

});

最初に、1回目と2回目のクリックにclickToggle関数を使用しました。2番目の関数はより重要です。setAttr_height()すべての.read-more要素の実際の高さが、ページの読み込み時にbase-height属性に設定されています。その後、ベースの高さがjquery css関数によって設定されます。

両方の属性を設定すると、これらの属性をスムーズに切り替えることができます。をdata-base希望の(固定)高さに変更し、自分のIDの.read-moreクラスを切り替えるだけです

フィドルFIDDLEで動作しているのがわかります

jQuery UIは不要


1

divの表示と非表示を切り替えるだけの場合は、このコードでjQuery animateを使用できます。jQueryで希望の高さの大部分をアニメーション化することも、0pxにアニメーション化してトリックアニメーション化することもできます。jQueryは、自動に変換するためにjQueryによって設定された高さを必要とします。したがって、.animateは.css(height:auto)が変換する要素にstyle = ""を追加します。

私がこの作品を見てきた最もクリーンな方法は、期待する高さのあたりまでアニメーション化し、それをautoに設定することです。正しく実行すると、非常にシームレスに見えます。あなたはあなたが期待するものを超えてアニメーション化することさえでき、それは元に戻ります。継続時間0で0pxにアニメーション化することは、単に要素の高さをその自動高さに落とすだけです。人間の目には、とにかくアニメーションのように見えます。楽しい..

    jQuery("div").animate({
         height: "0px"/*or height of your choice*/
    }, {
         duration: 0,/*or speed of your choice*/
         queue: false, 
         specialEasing: {
             height: "easeInCirc"
        },
         complete: function() {
             jQuery(this).css({height:"auto"});
        }
    });

申し訳ありませんが、これは古い投稿であることは承知していますが、この投稿に出くわしたjQueryを使用してこの機能を求めているユーザーにとっては、これは重要だと感じました。


0

私が探していたものを正確に実行し、見栄えの良いものをまとめました。要素のscrollHeightを使用すると、DOMに読み込まれたときの高さがわかります。

 var clickers = document.querySelectorAll('.clicker');
    clickers.forEach(clicker => {
        clicker.addEventListener('click', function (e) {
            var node = e.target.parentNode.childNodes[5];
            if (node.style.height == "0px" || node.style.height == "") {
                $(node).animate({ height: node.scrollHeight });
            }
            else {
                $(node).animate({ height: 0 });
            }
        });
    });
.answer{
        font-size:15px;
        color:blue;
        height:0px;
        overflow:hidden;
       
    }
 <div class="row" style="padding-top:20px;">
                <div class="row" style="border-color:black;border-style:solid;border-radius:4px;border-width:4px;">
                    <h1>This is an animation tester?</h1>
                    <span class="clicker">click me</span>
                    <p class="answer">
                        I will be using this to display FAQ's on a website and figure you would like this.  The javascript will allow this to work on all of the FAQ divs made by my razor code.  the Scrollheight is the height of the answer element on the DOM load.  Happy Coding :)
                         Lorem ipsum dolor sit amet, mea an quis vidit autem. No mea vide inani efficiantur, mollis admodum accusata id has, eam dolore nemore eu. Mutat partiendo ea usu, pri duis vulputate eu. Vis mazim noluisse oportere id. Cum porro labore in, est accumsan euripidis scripserit ei. Albucius scaevola elaboraret usu eu. Ad sed vivendo persecuti, harum movet instructior eam ei.
                    </p>
                </div>
            </div>
            <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.