0

A few days ago I asked how can I keep my scroll bar at the bottom when new data comes in. I got this answer which worked perfectly fine for me. But now I have a new requirement. I want the scroll bar to stay where I take it. For example, when the page loads and if I don't touch the scroll bar, then the scroll bar should remain at the bottom. But if I touch it and take it up, then it should stay there and not come down automatically.

This is the code I have:

<style>
#conversationDiv {
height: 900px;
overflow: auto;     
} 
</style>

<script>
$(function () {
  setInterval(function() {
    var element = document.getElementById("conversationDiv");
    element.scrollTop = element.scrollHeight;
  }, 0);
});
</script>


<div id="conversationDiv">

EDIT: I am posting the full code below which shows where the messages are coming from and where they are getting appended to what div.

<!DOCTYPE html>
<html>
<head>
<title>Hello WebSocket</title>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/sockjs-client/1.1.0/sockjs.js">   </script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/stomp.js/2.3.3/stomp.js"></script>
<script src="https://code.jquery.com/jquery-2.1.4.js"></script>
<style>
#conversationDiv {
height: 900px;
}
</style>
<script>
 $(function () {     
  setInterval(function() {       
   var element = document.getElementById("conversationDiv");
    element.scrollTop = element.scrollHeight;
   }, 0);
});  
</script>
<script type="text/javascript">
    var stompClient = null;
    function setConnected(connected) {
        document.getElementById('connect').disabled = connected;
        document.getElementById('disconnect').disabled = !connected;
        document.getElementById('conversationDiv').style.visibility = connected ? 'visible' : 'hidden';
        document.getElementById('response').innerHTML = '';
    }

    function connect() {
        var socket = new SockJS("http://twitchbot-farazdurrani.rhcloud.com:8000/hello/");
        stompClient = Stomp.over(socket);
        stompClient.connect({}, function(frame) {
            setConnected(true);
            console.log('Connected: ' + frame);
            stompClient.subscribe("/topic/greetings", function(greeting){
                showGreeting(greeting.body);
            });
        });
    }

    function disconnect() {
        if (stompClient != null) {
            stompClient.disconnect();
        }
        setConnected(false);
        console.log("Disconnected");
    }

    function sendName() { //I am not sending anything so remove this..
        var name = document.getElementById('name').value;
        stompClient.send("/app/hello", {}, JSON.stringify({ 'name': name     }));
    } 

    function showGreeting(message) {
        var response = document.getElementById('response');
        var p = document.createElement('p');
        p.style.wordWrap = 'break-word';
        p.appendChild(document.createTextNode(message));
        response.appendChild(p);
    }        
</script>
</head>
<body onload="connect()">
<div>
    <div>
        <button id="connect" onclick="connect();">Connect</button>
        <button id="disconnect" disabled="disabled" onclick="disconnect();">Disconnect</button>
    </div>
    <div id="conversationDiv" style="overflow:auto">            
        <p id="response"></p>
    </div>
</div>

A little info on what's going on: It is a one way chat system (Using WebSockets) where only one side send messages. That is server side. All the magic is happening in function showGreeting(message) {..} where it is creating elements and appending child, etc. I hope this could be of little help. Thanks

Community
  • 1
  • 1
Faraz
  • 6,025
  • 5
  • 31
  • 88

2 Answers2

1

For this you might need a flag. So what I am doing is:

  1. When the scroll event is fired (gets fired even when appending), we need to check if the scrolled part is at the end.
  2. If it is not end, we need to clear the interval.
  3. If it is the end, reinitialise the interval.

Not sure why it isn't work. I have got the script I was working here.

$(function () {
  var count = 1;
  setInterval(function () {
    $("#conversationDiv").append('<p>Message #' + count++ + ': Lorem ipsum dolor sit amet, consectetur adipisicing elit. Praesentium repudiandae doloribus unde, repellat maiores minus fuga earum esse, ab, aperiam voluptatibus est dolorem placeat perferendis omnis libero dolore alias quasi!</p>');
  }, 1000);
  var scr = setInterval(function() {
    var element = document.getElementById("conversationDiv");
    element.scrollTop = element.scrollHeight;
  }, 500);
  $("#conversationDiv").scroll(function () {
    var element = document.getElementById("conversationDiv");
    if ((Number(element.scrollTop) + Number($(element).height())) != (Number(element.scrollHeight)))
      clearInterval(scr);
    else
      if (element.scrollTop < element.scrollHeight)
      scr = setInterval(function() {
        var element = document.getElementById("conversationDiv");
        element.scrollTop = element.scrollHeight;
      }, 500);
  });
});
* {font-family: 'Segoe UI'; margin: 0; padding: 0; list-style: none;}

#conversationDiv {height: 350px; overflow: auto; border: 1px solid #ccc;}
#conversationDiv p {margin: 5px 5px 10px; padding: 5px; border: 1px solid #ccc; background-color: #f5f5f5;}
<script src="https://code.jquery.com/jquery-2.1.4.js"></script>
<div id="conversationDiv">
  
</div>

Looks like something is missing. I am almost near it. Should something be there in the area of Number(element.scrollTop), Number($(element).height()), Number(element.scrollHeight).

Praveen Kumar Purushothaman
  • 164,888
  • 24
  • 203
  • 252
1

You can figure out if you are scrolled to the bottom like this

var isScrolled = (element.scrollHeight - element.scrollTop === element.clientHeight);

then:

if (isScrolled) { 
   //code here to move scrollbar down
}

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

Williz
  • 309
  • 1
  • 9