javascriptjqueryscrollchat

Automatically scroll down chat div


I have this code, to load chat

function getMessages(letter) {
  var div = $('#messages');
  $.get('msg_show.php', function (data) {
    div.html(data);
  });
}

setInterval(getMessages, 100);

What I have to add, to automatically scroll down #messages div on page load, and again with every new chat post?

This doesn't work:

function getMessages(letter) {
  var div = $('#messages');
  $.get('msg_show.php', function (data) {
    div.html(data);
    $('#messages').scrollTop($('#messages')[0].scrollHeight);
  });
}

setInterval(getMessages, 100);

Solution

  • Let's review a few useful concepts about scrolling first:

    When should you scroll?

    Programmatically that is:

    if (firstTime) {
      container.scrollTop = container.scrollHeight;
      firstTime = false;
    } else if (container.scrollTop + container.clientHeight === container.scrollHeight) {
      container.scrollTop = container.scrollHeight;
    }
    

    Full chat simulator (with JavaScript):

    https://jsfiddle.net/apvtL9xa/

    const messages = document.getElementById('messages');
    
    function appendMessage() {
    	const message = document.getElementsByClassName('message')[0];
      const newMessage = message.cloneNode(true);
      messages.appendChild(newMessage);
    }
    
    function getMessages() {
    	// Prior to getting your messages.
      shouldScroll = messages.scrollTop + messages.clientHeight === messages.scrollHeight;
      /*
       * Get your messages, we'll just simulate it by appending a new one syncronously.
       */
      appendMessage();
      // After getting your messages.
      if (!shouldScroll) {
        scrollToBottom();
      }
    }
    
    function scrollToBottom() {
      messages.scrollTop = messages.scrollHeight;
    }
    
    scrollToBottom();
    
    setInterval(getMessages, 100);
    #messages {
      height: 200px;
      overflow-y: auto;
    }
    <div id="messages">
      <div class="message">
        Hello world
      </div>
    </div>