how to maintain scrollbar at the bottom, instead o

2019-07-23 07:36发布

问题:

I am making a chat where, on load, the scrollbar scrolls to the bottom. This is the JS function that gets called on load:

 <script>
function updateScroll() {
    var element = document.getElementById("chatlogs");
    var elementHeight = element.scrollHeight;
    element.scrollTop = elementHeight
}
window.onload = updateScroll;
 </script>

Then, with this code:

    $(document).ready(function(e) {       
            $.ajaxSetup({cache:false});
            setInterval(function() {$('#chatlogs').load('logs.php');}, 1000);
    });

..the chat gets updated every second. What happens though, is that when it updates, the scrollbar goes to the middle, instead of remaining at the bottom. How can I make my chat stay at the bottom, when the last code makes the chat refresh?

You can see a working example here: http://www.friendsinclass.co.nf/ Please let me know, thank you!

回答1:

A couple thoughts, first you'll probably want to use recursion to call the AJAX request on AJAX success. Using setInterval() could result in any number of AJAX requests happening at any given time, depending on how long they take to return.

Second, to prevent the scroll bar from jumping to the bottom if the user has scrolled, you'll probably want to give them a notice and the ability to jump to the bottom if there is new content.

Considering those points, something like this would work:

JavaScript

var infiniteUpdate = true;
var intervalTimer;
var id = 0;
var log = document.getElementById("chatlogs");


function updateScroll() {
    log.scrollTop = log.scrollHeight;
    $('#messagearea').hide()
}

function updateLog() {

    //if an interval timer was set, we clear it
    if(typeof intervalTimer == 'number') { 
        clearInterval(intervalTimer);
    } 
    id++;



    $.ajax({
      url: "http://jsonplaceholder.typicode.com/photos?id=" + id,
    })
    .done(function( data ) {

        //bottomOfScroll is the height .scrollTop must be at for the user to be at the bottom of the scrollbar
        var bottomOfScroll = log.scrollHeight - log.clientHeight;
        //isScrollable detects if the element can scroll
        var isScrollable = log.scrollHeight != log.clientHeight;

        //if the user is not at the bottom and the element has a scrollbar
        if(log.scrollTop != bottomOfScroll && isScrollable) {
            //when true, it means the user has scrolled
            hasUserScrolled = true;
        } else {
            //when false, we are still at the bottom of the element
            hasUserScrolled = false;
        }

        //append the new data
        $('#chatlogs').append('<p>'+data[0].title+'</p>')

        //if we had detected a scroll
        if(hasUserScrolled) {
            //show the message and allow the user to click to jump to the bottom
            $('#messagearea').show();
        } else {
            //if the user hasnt scrolled, move the scroll position to the bottom and hide the message
          updateScroll();
        }

        //if we wanted to do something to break recursion, we could do that here
        if(infiniteUpdate) { 
            //set a new timer for 2.5 seconds
            intervalTimer = setInterval( updateLog, 2500);
        }

    });

}


$(document).ready(function() {   
    $('#messagearea').on('click', updateScroll)

    updateScroll();
    updateLog();

});

HTML

<div id="chatlogs">

</div>
<div id="messagearea">Scroll Down to View New Messages
</div>

CSS

#chatlogs {
  height: 300px;
  width: 200px;
  overflow: scroll;
}

#messagearea { display: none; }

JS Fiddle example https://jsfiddle.net/igor_9000/9tbrgrkn/3/ with a test AJAX endpoint

Hope that helps!