Nerian
Nerian

Reputation: 16177

Animate the change of height of a div when its contents change

I have a div#menu that displays a list of information. That information changes via ajax. When it changes, I want to animate that transition from height A to height B.

I know I can use .animate({'height': 'something') but I don't know how to glue all this together.

I am using jQuery.

How can I do that?

Edit.

The ajax call looks like this:

$.ajax({
  url: $(this).data('redraw-event-url'),
     dataType: 'script'
     }) 

Upvotes: 7

Views: 8623

Answers (4)

Mala
Mala

Reputation: 14803

You'll need to do this in a couple of steps:

  • First, put the new data inside a different div, ideally hidden or not even on the dom.
  • Second, figure out how tall this second div is
  • Set the height of the first div via animate, and once the animation is finished, replace the content

so some code:

// put the content into a hidden div
$('#hiddendiv').html(content);

// get the target height
var newHeight = $('#hiddendiv').height();

// animate height and set content
$('#menu').animate({'height': newHeight}, function(){
    $('#menu').html($('#hiddendiv').html());
});

Upvotes: 1

Sheraff
Sheraff

Reputation: 6682

I believe I have a cleaner, better solution involving a container:

<div id="menu_container">
  <div id="menu">
    <p>my content</p>
  </div>
</div>

What I do is that I lock maxHeight and minHeight of the container to the current height of the div. Then I change the content of said div. And finally I "release" max and min height of the container to the current height of inner div:

$("#menu_container").css("min-height", $("#menu").height());
$("#menu_container").css("max-height", $("#menu").height());
$("#menu").fadeOut(500, function() {

    //insert here the response from your ajax call
    var newHtml = serverResponse;

    $(this).html(newHtml).fadeIn(500, function() {
        $("#menu_container").animate({minHeight:($("#menu").height())},500);
        $("#menu_container").animate({maxHeight:($("#menu").height())},500);
    });
});

Upvotes: 1

Daniele B
Daniele B

Reputation: 3125

A nice solution is to render the div#menu object on the success callback

$.ajax({
  url: $(this).data('redraw-event-url'),
     dataType: 'script',
     success: function(){
        $('div#menu').animate({'height': 'something');
        }
     })  

hope this helps

Upvotes: 0

Jasper
Jasper

Reputation: 75993

You can add the new HTML to the DOM off-screen so the user can't see it. Then get it's height, and change the height of the container just before moving the new HTML from the temporary off-screen location to it's final destination. Something like this:

$.ajax({
    success : function (serverResponse) {

        //add the new HTML to the DOM off-screen, then get the height of the new element
        var $newHTML  = $('<div style="position : absolute; left : -9999px;">' + serverResponse + '</div>').appendTo('body'),
            theHeight = $newHTML.height();

        //now animate the height change for the container element, and when that's done change the HTML to the new serverResponse HTML
        $('#menu').animate({ height : theHeight }, 500, function () {

            //notice the `style` attribute of the new HTML is being reset so it's not displayed off-screen anymore
            $(this).html($newHTML.attr('style', ''));
        });
    }
});

Upvotes: 8

Related Questions