-1

Hello Coders! I am coding a chat system, I would like the scroll bar to stay at the bottom. In this way when someone sends a message the user would not have to scroll down. I would also like it to start at the bottom of the page load. Additionally, the user can scroll up when needed, but when they scroll back down it locks in place. I have tried many times but for some reason it does not work, I was wondering if anyone has a method of doing this?

MtnBros
  • 55
  • 5
  • Can you show us what you have tried? – Dinesh Namburi Oct 12 '18 at 20:16
  • You should flip the results, so the newest is in the top :) – Ulrik McArdle Oct 12 '18 at 20:16
  • Or you could use scrollTop and document.offsetHeight – Ulrik McArdle Oct 12 '18 at 20:17
  • @UlrikMcArdle Could you elaborate I have tried the methods from: https://stackoverflow.com/questions/18614301/keep-overflow-div-scrolled-to-bottom-unless-user-scrolls-up/21067431 Which use that. – MtnBros Oct 12 '18 at 20:20
  • Get the position of the last element (if it is in af chat window) with let offsetHeight = document.querySelector('.chat-item').offsetHeight; and then use scrollTop on the chat window element - I haven't tried this, but in theory it should work. – Ulrik McArdle Oct 12 '18 at 20:25

3 Answers3

1

I've also have struggled with implementing this for a while. The approach I've ended up with relies on using MutationObservable

MutationObservable allows to watch for DOM changes inside element and perform some actions when deeply nested element is changed (in your case, for example, new comment was rendered):

// chatContainer is reference to your chatContainer element
var isLocked = true;

var mutationObserver = new MutationObserver(() => {
    if (isLocked) {
        scrollToBottom();
    }
});

mutationObserver.observe(chatContainer, {
    childList: true,
    subtree: true,
    attributes: false,
});

This gave me a callback, where I likely had to make chatContainer scroll to the bottom.

Scroll to the bottom implementation could be:

function scrollToBottom() {
    chatContainer.scrollTop = 99999999999;
}

To change isLocked flag, I had to listen for user scrolls on chatContainer and update it accordingly:

var LOCK_OFFSET = 25; // how many pixels close to bottom consider scroll to be locked
chatContainer.addEventListener('scroll', handleUserScroll);

function handleUserScroll() {
    var scrollFromBottom =
        chatContainer.scrollHeight -
        chatContainer.scrollTop -
        chatContainer.clientHeight; // how many pixels user scrolled up from button of the chat container.

    isLocked = scrollFromBottom > LOCK_OFFSET; // set new isLocked. lock, if user is close to the bottom, and unlock, if user is far from the bottom. 
});

Hope I've explained the general idea. This approach works fine for me. User scroll listening should be improved with events debouncing. And don't forget to dispose scroll event and mutation observer subscriptions.

Anton Dosov
  • 326
  • 2
  • 6
0

This is what I've used in my projects. It works on IE, Edge, Firefox, Chrome and Opera. I'm not sure about Safari.

var a = document.querySelector('#divchat');
a.scrollIntoView(false);

I hope it helps.

fvildoso
  • 415
  • 8
  • 12
0

There are a lot of answers for this question around.

Here is one of them from Automatically scroll down chat div

The main point of that answer is the variables scrollHeight, scrollTop, and clientHeight can be manipulated.

But basically, to scroll down it is to use container.scrollTop = container.scrollHeight;

  • Trust me, I am aware. None of these methods have worked. I will take a link a your linked post. – MtnBros Oct 12 '18 at 21:00