Christian Speegle
Christian Speegle

Reputation: 13

When using jQuery AJAX call, the scrollTop() function scrolls to the most recent item BEFORE AJAX call rather than AFTER

I am building a simple chat page for use by members of my website. The page is currently in production; right now, I have the page set to only check for new chat messages when a user sends a message. As part of the jQuery function including the $.ajax call, I have used a snippet of code suggested by the StackOverflow community to scroll to the bottom of the div containing the chats, but this code is behaving "on the wrong side" of the $.ajax call. My HTML is here:

<div id="chat">

</div>

<form id="chat-input">
   <textarea form="chat-input" id="message" name="message" placeholder="Type your message here..." autofocus></textarea>
</form>

This is my jQuery:

   $('#chat-input').submit(function() {
           var new_chat = $('textarea[name=message]').val();//gets the value of the message box to send
           var most_recent_chat = $('.chat-item:last-child').attr('data-chat-id');//gets the id# of the last chat
           $.ajax({
                url: "/docs/chat/chat.php",
                dataType: 'html',
                type: "post",
                data: {
                    new_chat: new_chat,
                    most_recent_chat: most_recent_chat,
                    new_sender: new_sender //Declared globally elsewhere
                },
                success: function(data) {
                    $('#chat').append(data);
                },
                    error: function(jqXHR, exception) {
                    //switch containing various errors
                    }           
                }
            });

           var divHeight = document.getElementById('chat').scrollHeight;
           $('div#chat').scrollTop(divHeight);
           document.getElementById('message').value='';
           event.preventDefault();
       });

My PHP script outputs this information (I output in HTML instead of JSON for simplicity at launch - will upgrade to JSON output at a later date):

<div class="chat-item" data-chat-id="(int)">//each chat has a unique id so that my php processing page only returns new chats
<p class="chat-message"><strong>(sender-name): </strong>(chat message)</p>
<p class="chat-time">(time of message)</p></div>

Now, for my exact problem. When I send a chat message, the $.ajax call works fine. My message arrives and is properly appended to the #chat div. However, these lines of code operates funny:

var divHeight = document.getElementById('chat').scrollHeight;
$('div#chat').scrollTop(divHeight);

My #chat div has a fixed height of 400px and the overflow is set to scroll. Many other Stack Overflow questions suggested that the above code would keep the #chat div scrolled to the bottom, and they do - sort of. Rather than setting the .scrollTop to the bottom AFTER the $.ajax call, these lines of code seem to set .scrollTop to the bottom BEFORE the $.ajax call (i.e., the second-to-most-recent chat is shown at the bottom of the div, with the most recent chat present but not scrolled to). The code is part of the form .submit() function, but is located after the $.ajax call. How can I alter my code to include the new chat messages when jQuery scrolls to the bottom?

If this matters, I am using AMPPS v3.5 with PHP v5.3 (my web host still uses 5.3) and I'm testing in Firefox 46.0.1.

Upvotes: 1

Views: 2821

Answers (1)

Jake Haller-Roby
Jake Haller-Roby

Reputation: 6427

Ajax calls are asynchronous. That means the code beneath them will execute while the call is pending.

So your scrollTop call executes before the ajax.success call.

If you want the scrolling to occur after the ajax call receives a response, include it in the success callback.

Upvotes: 1

Related Questions