6

My JQuery slide animation lags when sliding the #res div.

Any suggestions?

JQuery:

$(document).ready(function(){

$('select.first').change(function(){

    $(this).prop('disabled', true);
    var codata = $(this).val();
    var page = 1;

    $.ajax({

        type:'POST',
        url:'page.php',
        dataType:'json',
        data:{country:codata, page:page},
        success: function(data) {

            var result='';
            $.each(data, function(i,e) {
            result += "<div id='outer'>"+e.sDo+'</div>';
            });
            $('#res').html(result);

        }


    }).done(function(){$('#res').slideDown();});

});

});

CSS:

#res {

    background-color:gainsboro;
    border:1px solid gray;
    width:100%;
    display:none;
    padding-top:10px;
}


#outer {

    width:100px; 
    text-align:center; 
    border:1px dotted black;
    margin:0 0 10px 10px;
    display:inline-block;
    height:40px;

}
John
  • 1,619
  • 8
  • 24
  • 34
  • Can you provide an example of this lagging in a http://jsfiddle.net – Rory McCrossan Aug 06 '12 at 14:59
  • Does it lag, or does it jump. What does lag mean in this context? – Kevin B Aug 06 '12 at 15:02
  • Also, just a general observation, it looks like you have duplicate ID's (`outer`) which is invalid, though not relevant to your current problem. – Kevin B Aug 06 '12 at 15:04
  • @KevinB Yes it jumps. It slides for a second (for first row of results) and then jumps to the end. – John Aug 06 '12 at 15:05
  • 1
    @John That is a very common problem with the slideDown animation. The most common fix to it is to give the element a fixed width. jQuery calculates the width of that element by displaying it off the page to see how tall it is, then it slides it down to that height, then sets it to display: block and lets it set it's own hight. that's where the jump happens. Since it's width is 100%, jQuery has no way of knowing how wide it is supposed to be, at which point it gets a shorter height than expected, resulting in a jump. – Kevin B Aug 06 '12 at 15:07
  • I would do `$('select').promise().done(function(){$('#res').slideDown();});` For this scenario. – Ohgodwhy Aug 06 '12 at 15:07
  • @Ohgodwhy What would that do? The select isn't animating therefore it's animation queue promise object would never resolve, right? or it would instantly resolve, i forget. – Kevin B Aug 06 '12 at 15:14

3 Answers3

12

To slideDown an element without it jumping, the element must have a fixed width. Here's a demo to demonstrate. http://jsfiddle.net/WtkUW/1/

The reason for this is jQuery calculates the target height of the element based on its width and its content. If its width is 100%, jQuery can't accurately calculate the height resulting in a jump. The larger the content, the larger the jump.

Kevin B
  • 94,570
  • 16
  • 163
  • 180
1

First of all, how fast is your page.php sending a response? That may be the answer entirely.

Second, you're using 2 competing methods for getting stuff done once the ajax call is complete: A) the success parameter of the .ajax() call, and B) the newer .done() function.

A. will be deprecated as of jQuery 1.8 (see: jQuery.ajax handling continue responses: "success:" vs ".done"?)

Why not put everything in .done():

$.ajax({
    type:'POST',
    url:'page.php',
    dataType:'json',
    data:{country:codata, page:page}    
})
.done( function(data) {

    var result='';
    $.each(data, function(i,e) {
    result += "<div id='outer'>"+e.sDo+'</div>';
    });
    $('#res').html(result);

    $('#res').slideDown();
});

Hard to know without seeing the execution, but mixing these could also be the source of unexpected behavior.

Community
  • 1
  • 1
Faust
  • 15,130
  • 9
  • 54
  • 111
0

To anyone who still has an issue with this, my problem was that I had my padding set with !important which presumably was overriding the animation's effects

Ree
  • 11