Анимировать элемент для автоматической высоты с помощью jQuery

Я хочу анимировать <div> с высоты 200px до auto. Я не могу заставить его работать, хотя. Кто-нибудь знает как?

Вот код:

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

Ответ 1

  • Сохранить текущую высоту:

    var curHeight = $('#first').height();
    
  • Временно переключите высоту на авто:

    $('#first').css('height', 'auto');
    
  • Получить максимальную высоту:

    var autoHeight = $('#first').height();
    
  • Вернитесь к 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);

Ответ 2

IMO это самое простое и простое решение:

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

Объяснение: DOM уже знает из своего первоначального рендеринга, какой размер будет иметь расширенный div, если он установлен на автоматическую высоту. Это свойство хранится в DOM node как scrollHeight. Нам просто нужно получить элемент DOM из элемента jQuery, вызвав get(0), а затем мы можем получить доступ к этому свойству.

Добавление функции обратного вызова для установки высоты на авто позволяет повысить отзывчивость после завершения анимации (кредит chris-williams):

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

Ответ 3

Это в основном тот же подход, что и ответ Box9, но я завернул его в хороший плагин 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);

изменить: теперь цепляется и очищается

Ответ 4

Лучшее решение не будет полагаться на 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

Ответ 5

это работает, и это проще, чем решения до:

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

Ответ 6

var h = document.getElementById('First').scrollHeight;
$('#First').animate({ height : h+'px' },300);

Ответ 7

Вы всегда можете обернуть дочерние элементы #first и сохранить высоту высоты обертки как переменной. Это может быть не самый красивый или самый эффективный ответ, но он делает трюк.

Здесь fiddle, где я включил reset.

но для ваших целей здесь мясо и картофель:

$(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            
    })
});
});​

Ответ 8

Мне удалось это исправить: D heres code.

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

Ответ 9

Используйте slideDown и slideUp

$("div:first").click(function(){ $("#first").slideDown(1000); });

Ответ 10

Как правило, высота автоматически доступна только после визуализации элемента. Если вы устанавливаете фиксированную высоту или если ваш элемент не отображается, вы не можете получить к нему доступ без каких-либо трюков.

К счастью, есть некоторые трюки, которые вы можете использовать.

Клонировать элемент, отобразить его вне представления, дать ему высоту 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); 
});

Ответ 11

вы всегда можете это сделать:

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/

Ответ 12

Вы можете заставить Liquinaut реагировать на изменения размера окна, добавив обратный вызов, который устанавливает высоту обратно в авто.

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

Ответ 13

Ваши селекторы, похоже, не совпадают. У вашего элемента есть идентификатор "first", или это первый элемент в каждом div?

Более безопасным решением было бы использовать 'this':

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

Ответ 14

Попробуйте это,

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 );
});

Ответ 15

Здесь, который работает с BORDER-BOX...

Привет, ребята. Вот плагин jQuery, который я написал, чтобы сделать то же самое, но также учитывать различия в высоте, которые будут иметь место, если у вас box-sizing установлено значение border-box.

Я также включил плагин "yShrinkOut", который скрывает элемент, сокращая его вдоль оси y.


// -------------------------------------------------------------------
// 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)();
        });
};

Любой из параметров, которые я использовал, может быть опущен или установлен в нуль, чтобы принимать значения по умолчанию. Параметры, которые я использовал:

  • growTo: Если вы хотите переопределить все вычисления и установить высоту CSS, к которой будет расти объект, используйте этот параметр.
  • продолжительность: Продолжительность анимации (очевидно).
  • ifComplete:. Функция, которая будет запущена после завершения анимации.

Ответ 16

Переключить слайд (ответ 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>

Ответ 17

Я отправляю этот ответ, хотя этот поток устарел. Я не мог принять принятый ответ на работу для меня. Это хорошо работает и довольно просто.

Я загружаю высоту каждого 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, но вы можете сделать анимировать то же самое.

Ответ 19

вы можете сохранить его в атрибуте данных.

$('.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);
    }
});

Ответ 20

Мне нужна эта функциональность для нескольких областей чтения на одной странице, реализующих это в коротком коде Wordpress. Я столкнулся с той же проблемой.

Технически технически весь пробег на странице имеет фиксированную высоту. И я хотел, чтобы они могли развернуть их отдельно к автоматической высоте с помощью переключателя. Первый щелчок: "expand to full height of text span", второй щелчок: "свернуть до высоты по умолчанию 70px"

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, который я использовал для хранения фактической (динамической) высоты элемента.

Часть 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);
    });

});

Сначала я использовал функцию clickToggle для первого и второго кликов. Вторая функция важнее: setAttr_height() Все элементы .read-more имеют фактическую высоту, установленную для загрузки страницы в атрибуте base-height. После этого базовая высота устанавливается через функцию jquery css.

С обоими нашими наборами атрибутов мы теперь можем переключаться между ними плавно. Только измените data-base на желаемую (фиксированную) высоту и переключите класс .read-more для своего собственного идентификатора

Вы все видите, что он работает в скрипке FIDDLE

Не требуется jQuery UI

Ответ 21

Если все, что вам нужно, это показать и скрыть, скажем, div, то этот код позволит вам использовать jQuery animate. Вы можете сделать так, чтобы jQuery анимировал большую часть желаемой высоты, или вы можете обмануть, оживив до 0px. jQuery просто нужна высота, установленная jQuery, чтобы преобразовать ее в авто. Поэтому .animate добавляет style = "" к элементу, который преобразует .css(height: auto).

Самый чистый способ, которым я видел эту работу, состоит в том, чтобы анимировать примерно на ожидаемую высоту, а затем дать ей установить авто, и она может выглядеть очень плавно, если все сделано правильно. Вы даже можете оживить прошлое, что вы ожидаете, и оно вернется назад. Анимация до 0px при длительности 0 просто снижает высоту элемента до его автоматической высоты. Человеческому глазу все равно это выглядит оживленно. Наслаждайтесь..

    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, которые сталкиваются с этим постом.

Ответ 22

Я собрал что-то, что делает именно то, что я искал и выглядит великолепно. Использование 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 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>