I'm late again, but here's my two cents.
Sometimes when measuring dynamic elements using only one reading can be misguiding because the content being appended might be long, or because the request ($.get, $.post, $.ajax, etc...) for content is still in the air. If the string being appended is coming from a request, then you have to use a callback method to append the response.
The best thing you can do is string it together like this, because javascript "should" resolve the functions synchronous fashion:
$("#textdiv").append('The longest string ever parsed goes here.')
.animate({scrollTop: $('#textdiv').prop("scrollHeight")}, 500);
But you're right, this method tends to be buggy, especially while dealing with divs that mutate fast enough.
That's why if you want to be extra sure that the job gets done, you could use an Interval:
var scroll_to_bottom = function(element){
var tries = 0, old_height = new_height = element.height();
var intervalId = setInterval(function() {
if( old_height != new_height ){
// Env loaded
clearInterval(intervalId);
element.animate({ scrollTop: new_height }, 'slow');
}else if(tries >= 30){
// Give up and scroll anyway
clearInterval(intervalId);
element.animate({ scrollTop: new_height }, 'slow');
}else{
new_height = content.height();
tries++;
}
}, 100);
}
$('#textdiv').append('The longest string ever parsed goes here.');
scroll_to_bottom($('#textdiv'));
This method cant beat a callback or a simple function line up, but it solves the problem if you don't know exactly when the append is going to end.