ThatPurpleGuy
ThatPurpleGuy

Reputation: 456

Auto Scroll down but stop when user scrolls

I have a chat box where people will beable to add there own message to it but my problem is that when new messages are added it does not scroll down to reveal the new message. I fixed this by using this code

 $('.panel-body').scrollTop($('.panel-body').height()*$('.panel-body').height());

(panel-body is the class of my scrolling div)

But the problem with this is that if a user wants to scroll back up at previous messages he or she will be forced back down to the bottom. What would be the best way to stop "auto scrolling" when the user scrolls but when the user scrolls back down or just loads the page it would start up again.

 function addMsg(is_admin, name, mes, time) {

    var newDiv = document.createElement("div");
    newDiv.className = "row";
    var p = document.createElement("p");
    p.className = "text-muted name";
    var p2 = document.createElement("p");
    var text = document.getElementById("start");
    var hr = document.createElement("hr");
    var times = document.createElement("p")
    text.appendChild(newDiv);
    newDiv.appendChild(p);
    p.innerHTML = name + ":";
    newDiv.appendChild(p2);
    newDiv.appendChild(times)
    times.className = "time";



    if (is_admin) {
        p.style = "color: red;";
        p2.innerHTML = mes;
        times.innerHTML = "time: " + time;


    } else {


        p2.innerHTML = mes;
        times.innerHTML = time;

    }
    newDiv.appendChild(hr);

This is my addMsg Function that i have already created

Upvotes: 3

Views: 2951

Answers (1)

Jon Uleis
Jon Uleis

Reputation: 18649

Here's a quick attempt I threw together.

By subtracting the element's height() (jQuery) from its scrollHeight (JS) and comparing that to the user's scrollTop (jQuery scroll position), we can determine if we're currently at the bottom of the scrollable container before the new message appears.

If we are at the bottom, then keep the user down there by setting the new scrollTop. Otherwise, don't change anything. Hope this helps!

Live demonstration:

function newMsg() {
  // FOR DEMO (naming each message)
  var count = $('.msg').length;

  // shouldScroll will be true if we're at the bottom of the
  // scrollable container before the new message appears
  var $panel = $('.panel-body');
  var shouldScroll = $panel[0].scrollHeight - $panel.height() <= $panel.scrollTop(); 

  // this is where you append a new message to the container
  $panel.append('<div class="msg">Message ' + count + '</div>');

  // if we were at the bottom before the new message,
  // then scroll to the new bottom of the container
  if (shouldScroll) {
    $panel.scrollTop($panel[0].scrollHeight);
  }
}

// FOR DEMO (new message every .5 seconds)
setInterval(newMsg, 500);
.panel-body {
  border: 1px solid #000;
  overflow: auto;
  width: 200px;
  height: 200px;
}

.msg {
  border-bottom: 1px solid #ccc;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="panel-body"></div>

Upvotes: 3

Related Questions