0

I'm designing a basic chat webpage, but whenever there are more messages than the screen can display without scrolling down, you have to scroll down to see newer messages. is there a way to fix this so that the webpage auto-scrolls (or some similar solution) when a new message is sent? any help would be greatly appreciated. here is my HTML:

<!doctype html>
<html>
  <head>
    <title>QuickChat</title>
    <style>
      * { margin: 0; padding: 0; box-sizing: border-box; }
      body { font: 13px Helvetica, Arial; text-align: center; }
      form { background: #666666; padding: 3px; position: fixed; bottom: 0; width: 100%; }
      form input { border: 100; padding: 10px; width: 90%; margin-right: .5%; }
      form button { width: 9%; background: #FFCC00; border: none; padding: 10px; }
      #messages { list-style-type: none; margin: 0; padding: 0; }
      #messages li { padding: 5px 10px; }
      #messages li:nth-child(odd) { background: #eee; }
      main {text-align: center; margin: 0; }
    </style>
  <form action="">
    <input id="m" autocomplete="off" /><button>Send!</button>
    </form>
  <text>[SYSTEM]: Welcome to the chat! two things you should know: 1. There are no usernames.
      I'm working on it, but for right now you can type your messages like [your name] [your message].
      2. This chat is fairly secure, but PLEEEASE don't send any secret stuff accross it (like passwords) unless absolutely necessary.
      Thanks for using my website! -C
  </text>
  </head>
<script src="/socket.io/socket.io.js"></script>
<script src="https://code.jquery.com/jquery-1.11.1.js"></script>
<script>
$(function () {
    var socket = io();
    $('form').submit(function(){
      socket.emit('chat message', $('#m').val());
      $('#m').val('');
      return false;
    });
    socket.on('chat message', function(msg){
      $('#messages').append($('<li>').text('[USER]: ' + msg));
    });
  });
  </script> 

  <body>
  <div id="main">
  <ul id="messages"></ul>
  </div>
  </body>
</html>
  • 1
    Possible duplicate of [How to auto-scroll to end of div when data is added?](https://stackoverflow.com/questions/7303948/how-to-auto-scroll-to-end-of-div-when-data-is-added) – Blue Jul 29 '18 at 14:25
  • Possible duplicate of [Scroll to bottom of div?](https://stackoverflow.com/questions/270612/scroll-to-bottom-of-div) – Dan O Jul 29 '18 at 14:57

3 Answers3

2

You could just call scrollIntoView() on the <li>, when you append it, like:

$('<li>').text('[USER]: ' + msg).appendTo('#messages').get(0).scrollIntoView();

https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView

The Element.scrollIntoView() method scrolls the element on which it's called into the visible area of the browser window.

You should also set scroll-behavior to smooth in your stylesheet, to stop the browser from 'jumping' to the target.

https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-behavior

The scroll-behavior CSS property specifies the scrolling behavior for a scrolling box when scrolling is triggered by one of the navigation or CSSOM scrolling APIs.

1

You can add this to the code after the message is sent.

socket.on('chat message', function(msg){
  $('#messages').append($('<li>').text('[USER]: ' + msg));
  var objDiv = document.getElementById("messages");
  objDiv.scrollTop = objDiv.scrollHeight;
});

body {
  overflow-x: hidden;
  overflow-y: visible;
}

#messages{
   width: 300px;
   height: 200px;
   overflow-x: hidden;
   overflow-y: visible;
   background-color: dodgerblue;
}

#messages > span{
  position: relative;
  top: 2000px;
}
<button onClick="scrollToBottom('messages')">Scroll To Bottom</button>
<div id="messages">
<div style="width: 100%; text-align: center; font-size: 20px;">Header</div>
<span>Bottom of div</span>
</div>
<button onClick="scrollToTop('messages')">Scroll To Top</button>
<script>
function scrollToBottom (id) {
   var div = document.getElementById(id);
   div.scrollTop = div.scrollHeight - div.clientHeight;
}
function scrollToTop (id) {
   var div = document.getElementById(id);
   div.scrollTop = 0;
}
</script>

If you want to scroll smoothly to the bottom (or to the top) of the div, you can use jQuery's animate().

body {
      overflow-x: hidden;
      overflow-y: visible;
    }

    #messages{
       width: 300px;
       height: 200px;
       overflow-x: hidden;
       overflow-y: visible;
       background-color: dodgerblue;
    }

    #messages > span{
      position: relative;
      top: 2000px;
    }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button onClick="scrollToBottom('messages')">Smoothly Scroll To Bottom</button>
    <div id="messages">
    <div style="width: 100%; text-align: center; font-size: 20px;">Header</div>
    <span>Bottom of div</span>
    </div>
    <button onClick="scrollToTop('messages')">Smoothly Scroll To Top</button>
    <script>
    function scrollToBottom (id) {
       var div = document.getElementById(id);
   $('#' + id).animate({
      scrollTop: div.scrollHeight - div.clientHeight
   }, 500);
    }
    function scrollToTop (id) {
      var div = document.getElementById(id);
   $('#' + id).animate({
      scrollTop: 0
   }, 500);
    }
    </script>
Unmitigated
  • 76,500
  • 11
  • 62
  • 80
0

After you add the new message call - $('#messages').scrollTop($('#messages').prop('scrollHeight'))

Programmer
  • 1,973
  • 1
  • 12
  • 20