it-swarm-ru.tech

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

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

Вот код:

$("div:first").click(function(){
  $("#first").animate({
    height: "auto"
  }, 1000 );
});
164
Daniel
  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);
246
David Tang

ИМО это самое чистое и простое решение:

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

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

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

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

По сути, это тот же подход, что и в ответе Box9, но я обернул его в Nice плагин jquery that принимает те же аргументы, что и обычная анимация, когда вам нужно иметь больше анимированных параметров и надоело повторять один и тот же код снова и снова:

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

edit: теперь цепной и чище

24
w0ps

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

23
Tim Hettler

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

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

11
czLukasss
var h = document.getElementById('First').scrollHeight;
$('#First').animate({ height : h+'px' },300);
8
Ignacio Martínez

Вы всегда можете обернуть дочерние элементы #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            
    })
});
});​
7
Usha

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

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

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

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

По сути, высота 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); 
});
4
Stan George

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

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

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

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/

3
Zuriel

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

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

Вот тот, который работает с 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, до которой будет расти объект, используйте этот параметр.
  • duration: Продолжительность анимации ( очевидно ).
  • whenComplete: Функция, запускаемая после завершения анимации.
2
Lopsided

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

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

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

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

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

Технически дизайн всех разделов read more на странице имеет фиксированную высоту. И я хотел иметь возможность расширять их отдельно до автоматической высоты с помощью переключателя. Первый щелчок: "развернуть до полной высоты текстового промежутка", второй щелчок: "свернуть до высоты по умолчанию 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, который я использовал для хранения фактической (динамической) высоты элемента.

Часть 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 на свой собственный ID

Вы все можете видеть, как это работает в скрипке FIDDLE

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

1
Paul

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

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

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

Я загружаю высоту каждого деления в данные

$('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, но вы можете сделать animate точно так же.

1
Leeish