0

Surely, this question has been asked and answered in different shades, but i'm a noob and i'm lost. I was following a tutorial on YouTube by WebDevJourney about Node.js, Socket.io and a Chat App; he skipped the part of implementing a 'disable scroll to bottom when a user is scrolling old messages and another user posts a message' because it should be easy to solve with a quick Google search.

I posted a auto-click function within Chrome to posts messages. And then in another window, acting like another user. I want to be able to scroll and read older messages, without being yeeted to the bottom everytime my auto-click user postes a new message.

These probably took me the closest to a solution: Keep overflow div scrolled to bottom unless user scrolls up and this one Keep the scroll at the bottom unless user changes the position of the scroll.

Here i am two days later, victim to my own persistence (or stupidity) and I would appreciate a helping hand guys.

This in the before mentioned function:

function scrollToBottom () {
  let messages = document.querySelector('#messages').lastElementChild;
  messages.scrollIntoView();
}

The function is called in this function which creates new messages:

socket.on('newMessage', function (message) {
  const formattedTime = moment(message.createdAt).format('LTS');
  const template = document.querySelector('#message-template').innerHTML;
  const html = Mustache.render(template, {
    from: message.from,
    text: message.text,
    createdAt: formattedTime
  });

  const div = document.createElement('div');
  div.innerHTML = html;

  document.querySelector('#messages').appendChild(div);
  scrollToBottom();
});

And my div looks like this:

    <div class="chat__main" id="scrollsolve">
        <ol id="messages" class="chat__messages"></ol>

        <div class="chat__footer">
            <form id="message-form">
                <input name="message" type="text" placeholder="Message" autofocus autocomplete="off" />
                <button type="submit" id="submit-btn">Send</button>
            </form>
            <button type="button" id="send-location">Send Location</button>
        </div>
    </div>

My div is styled with CSS like this:

.chat__main {
    display: flex;
    flex-direction: column;
    height: 100vh;
    width: 100%
}

.chat__messages {
    flex-grow: 1;
    overflow-y: scroll;
    -webkit-overflow-scrolling: touch;
    padding: 10px
}

I tried following the guidelines in here, but i'm sure i missed some steps! I hope the amount of code helps towards clarification instead of confusement. If not, please write what could further clarification.

1 Answers1

0

This is the code I use in my chatsystem for auto scrolling. Basicly it checks if the scroll bar is at the bottom (or close to) and scrolls automaticly down. If it's not, it doesn't.

Just change the number 450 to whatever you feel is suitable. The lower the number, the smaller the threshold:

const elem = document.getElementById('messages');
const scrollDiff = (elem.scrollHeight - elem.scrollTop) - elem.clientHeight;

if(scrollDiff < 450){
    elem.scrollTop = elem.scrollHeight;
}

You should be able to just put that inside your scrollToBottom () function.

icecub
  • 8,615
  • 6
  • 41
  • 70
  • Thank you so much! This is how my function ended up, the comments being the old function: function scrollToBottom () { const elem = document.getElementById('messages'); const scrollDiff = (elem.scrollHeight - elem.scrollTop) - elem.clientHeight; if (scrollDiff < 450) { elem.scrollTop = elem.scrollHeight; } // let messages = document.querySelector('#messages').lastElementChild; // messages.scrollIntoView(); } ``` – LoneScavengah Nov 11 '19 at 15:27
  • @PastOfTear Seems fine to me. Glad I could be of help :) – icecub Nov 11 '19 at 22:17