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

Я хочу анимировать

от 200px до auto высоты. Я не могу заставить его работать. Кто-нибудь знает как?

Вот код:

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

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

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

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

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

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

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

Это в основном тот же подход, что и ответ 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); 

edit: теперь цепляется и чище

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

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

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

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

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

Вот скрипка, где я включил сброс.

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

 $(function(){ //wrap everything inside #first $('#first').children().wrapAll('
'); //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 }) }); });​

Использование slideDown и slideUp

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

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

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

В принципе, высота 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); }); 

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

 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/

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Html

   /* Lots of text determining the height of this span */   

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); }); }); для 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 на нужную (фиксированную) высоту и переключите class .read-more для своего собственного идентификатора

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

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

Переключить слайд ( ответ 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;} 
  
Lorem ipsum dolor sit amet, consectetur adipiscing elit
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,