Quero animar um <div>
a partir 200px
de auto
altura. Eu não consigo fazê-lo funcionar embora. Alguém sabe como?
Aqui está o código:
$("div:first").click(function(){
$("#first").animate({
height: "auto"
}, 1000 );
});
Quero animar um <div>
a partir 200px
de auto
altura. Eu não consigo fazê-lo funcionar embora. Alguém sabe como?
Aqui está o código:
$("div:first").click(function(){
$("#first").animate({
height: "auto"
}, 1000 );
});
Respostas:
Salve a altura atual:
var curHeight = $('#first').height();
Altere temporariamente a altura para automático:
$('#first').css('height', 'auto');
Obtenha a altura automática:
var autoHeight = $('#first').height();
Volte para curHeight
e anime para autoHeight
:
$('#first').height(curHeight).animate({height: autoHeight}, 1000);
E juntos:
var el = $('#first'),
curHeight = el.height(),
autoHeight = el.css('height', 'auto').height();
el.height(curHeight).animate({height: autoHeight}, 1000);
.animated({height: autoHeight}, 1000, function(){ el.height('auto'); });
opacity: 0; position: absolute;
enquanto o mede e removendo aqueles quando terminar.
Na IMO, esta é a solução mais limpa e fácil:
$("#first").animate({height: $("#first").get(0).scrollHeight}, 1000 );
Explicação: O DOM já sabe, desde sua renderização inicial, qual o tamanho que a div expandida terá quando definida como altura automática. Esta propriedade é armazenada no nó DOM como scrollHeight
. Nós apenas temos que buscar o elemento DOM do elemento jQuery chamando get(0)
e então podemos acessar a propriedade
A adição de uma função de retorno de chamada para definir a altura como automática permite maior capacidade de resposta assim que a animação estiver concluída (credit chris-williams ):
$('#first').animate({
height: $('#first').get(0).scrollHeight
}, 1000, function(){
$(this).height('auto');
});
clientHeight
que parece não ser suportado: developer.mozilla.org/en-US/docs/Web/ API / Element.clientHeight
$('#first').animate({ height: $('#first').get(0).scrollHeight }, 1000, function() { $(this).height('auto'); });
scrollWidth
animações de largura.
Essa é basicamente a mesma abordagem que a resposta do Box9, mas eu a envolvi em um bom plugin de jquery que usa os mesmos argumentos de uma animação normal , pois quando você precisa ter mais parâmetros animados e se cansa de repetir o mesmo código repetidamente :
;(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);
editar: encadeado e limpador agora
Uma solução melhor não dependeria do JS para definir a altura do seu elemento. A seguir, é apresentada uma solução que anima um elemento de altura fixa para a altura total ("automática"):
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);
height
um valor fixo (por exemplo, 122px). Meu elemento mudou altura depois de um tempo, então eu tive que substituir o argumento de duração (400) com opções{duration: 400, complete: function() {$selector.css('height', 'auto');}}
isso está funcionando e é mais simples que as soluções anteriores:
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");
}
})
});
Nota: Esta solução requer jQuery UI
.addClass
e .removeClass
?
var h = document.getElementById('First').scrollHeight;
$('#First').animate({ height : h+'px' },300);
Você sempre pode agrupar os elementos filhos de #first e salvar a altura height do wrapper como uma variável. Essa pode não ser a resposta mais bonita ou mais eficiente, mas funciona.
Aqui está um violino onde eu incluí uma redefinição.
mas para seus propósitos, aqui está a carne e as batatas:
$(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
})
});
});
Você pode fazer com que a resposta do Liquinaut responda a alterações no tamanho da janela adicionando um retorno de chamada que ajusta a altura novamente para automático.
$("#first").animate({height: $("#first").get(0).scrollHeight}, 1000, function() {$("#first").css({height: "auto"});});
Basicamente, a altura automática está disponível apenas para você depois que o elemento é renderizado. Se você definir uma altura fixa ou se seu elemento não for exibido, não será possível acessá-lo sem truques.
Felizmente, existem alguns truques que você pode usar.
Clone o elemento, exiba-o fora da visualização, dê-lhe a altura automática e você pode retirá-lo do clone e usá-lo mais tarde para o elemento principal. Eu uso essa função e parece funcionar bem.
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);
});
}
USO:
$(".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);
});
você sempre pode fazer isso:
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);
});
}
aqui está um violino: http://jsfiddle.net/Zuriel/faE9w/2/
.appendTo("body")
por.appendTo(el.parent())
Seus seletores parecem não corresponder. Seu elemento tem um ID de 'primeiro' ou é o primeiro elemento em cada div?
Uma solução mais segura seria usar 'this':
// assuming the div you want to animate has an ID of first
$('#first').click(function() {
$(this).animate({ height : 'auto' }, 1000);
});
$(this)
dentro do seu manipulador de cliques.
animate({height: 'auto'})
não tem nenhum efeito. Pelo menos, não com o jQuery 1.6.4.
Tente este ,
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 );
});
Oi pessoal. Aqui está um plugin jQuery que escrevi para fazer o mesmo, mas também leve em consideração as diferenças de altura que ocorrerão quando você box-sizing
definirborder-box
.
Também incluí um plug-in "yShrinkOut" que oculta o elemento, reduzindo-o ao longo do eixo 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)();
});
};
Qualquer um dos parâmetros que eu usei pode ser omitido ou definido como nulo para aceitar valores padrão. Os parâmetros que eu usei:
Alternar slide ( resposta do Box9 expandida)
$("#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>
Estou postando esta resposta mesmo que este tópico seja antigo. Não consegui que a resposta aceita funcionasse para mim. Este funciona bem e é bem simples.
Carrego a altura de cada div que eu quero nos dados
$('div').each(function(){
$(this).data('height',$(this).css('height'));
$(this).css('height','20px');
});
Então eu apenas uso isso ao animar no clique.
$('div').click(function(){
$(this).css('height',$(this).data('height'));
});
Estou usando a transição CSS, portanto, não uso o jQuery animate, mas você pode animar da mesma forma.
você pode armazená-lo em um atributo de dados.
$('.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);
}
});
Eu precisava dessa funcionalidade para várias áreas de mais leitura em uma página, implementando isso em um código de acesso do Wordpress. Corri para o mesmo problema.
Projete tecnicamente todas as extensões de leitura mais na página têm uma altura fixa. E eu queria poder expandi-los separadamente para uma altura automática com uma alternância. Primeiro clique: 'expandir para a altura total do espaço de texto', segundo clique: 'reduzir para a altura padrão de 70 px'
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;
}
Então, acima disso, parece muito simples o data-base
atributo que eu preciso para definir a altura fixa necessária. odata-height
atributo que eu usei para armazenar a altura (dinâmica) real do elemento.
A parte do 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);
});
});
Primeiro, usei a função clickToggle para o meu primeiro e segundo clique. A segunda função é mais importante: setAttr_height()
todos os .read-more
elementos têm suas alturas reais definidas no carregamento da página no base-height
atributo. Depois disso, a altura da base é definida através da função jquery css.
Com os dois atributos definidos, agora podemos alternar entre eles de maneira suave. Apenas altere odata-base
para sua altura desejada (fixo) e mudar a classe .read-mais para o seu próprio ID
Todos vocês podem vê-lo trabalhando em um violino FIDDLE
Não é necessária interface do usuário do jQuery
Se tudo o que você deseja é mostrar e ocultar, digamos uma div, esse código permitirá que você use o jQuery animate. Você pode fazer com que o jQuery anime a maior parte da altura desejada ou você pode enganá-lo animando para 0px. O jQuery precisa apenas de uma altura definida pelo jQuery para convertê-lo em automático. Portanto, o .animate adiciona o estilo = "" ao elemento que .css (height: auto) converte.
A maneira mais limpa de ver este trabalho é animar ao redor da altura esperada e deixá-lo definir automaticamente e ele pode parecer muito perfeito quando feito da maneira certa. Você pode até animar o que você espera e ele voltará. A animação para 0px com uma duração de 0 simplesmente reduz a altura do elemento à sua altura automática. Para o olho humano, parece animado de qualquer maneira. Aproveitar..
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"});
}
});
Desculpe, eu sei que esta é uma postagem antiga, mas achei que isso seria relevante para os usuários que procuram essa funcionalidade ainda com o jQuery que se deparam com essa publicação.
Eu montei algo que faz exatamente o que eu estava procurando e parece ótimo. O uso do scrollHeight de um elemento fornece a altura de quando ele foi carregado no 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>