[javascript] Scroll to bottom of div?

I am creating a chat using Ajax requests and I'm trying to get messages div to scroll to the bottom without much luck.

I am wrapping everything in this div:

#scroll {
    height:400px;
    overflow:scroll;
}

Is there a way to keep it scrolled to the bottom by default using JS?

Is there a way to keep it scrolled to the bottom after an ajax request?

This question is related to javascript html ajax chat

The answer is


smooth scroll with Javascript:

document.getElementById('messages').scrollIntoView({ behavior: 'smooth', block: 'end' });


Using jQuery, scrollTop is used to set the vertical position of scollbar for any given element. there is also a nice jquery scrollTo plugin used to scroll with animation and different options (demos)

var myDiv = $("#div_id").get(0);
myDiv.scrollTop = myDiv.scrollHeight;

if you want to use jQuery's animate method to add animation while scrolling down, check the following snippet:

var myDiv = $("#div_id").get(0);
myDiv.animate({
    scrollTop: myDiv.scrollHeight
  }, 500);

using jQuery animate:

$('#DebugContainer').stop().animate({
  scrollTop: $('#DebugContainer')[0].scrollHeight
}, 800);

I know this is an old question, but none of these solutions worked out for me. I ended up using offset().top to get the desired results. Here's what I used to gently scroll the screen down to the last message in my chat application:

$("#html, body").stop().animate({
     scrollTop: $("#last-message").offset().top
}, 2000);

I hope this helps someone else.


use :

var element= $('element');
var maxScrollTop = element[0].scrollHeight - element.outerHeight();
element.scrollTop(maxScrollTop);

or check scroll to bottom :

    var element = $(element);
    var maxScrollTop = element[0].scrollHeight - element.outerHeight();
    element.on('scroll', function() {
        if ( element.scrollTop() >= maxScrollTop ) {
            alert('scroll to bottom');
        }
    });

Java Script:

document.getElementById('messages').scrollIntoView(false);

Scrolls to the last line of the content present.


Found this really helpful, thank you.

For the Angular 1.X folks out there:

angular.module('myApp').controller('myController', ['$scope', '$document',
  function($scope, $document) {

    var overflowScrollElement = $document[0].getElementById('your_overflow_scroll_div');
    overflowScrollElement[0].scrollTop = overflowScrollElement[0].scrollHeight;

  }
]);

Just because the wrapping in jQuery elements versus HTML DOM elements gets a little confusing with angular.

Also for a chat application, I found making this assignment after your chats were loaded to be useful, you also might need to slap on short timeout as well.


If you don't want to rely on scrollHeight, the following code helps:

$('#scroll').scrollTop(1000000);

You can use the HTML DOM scrollIntoView Method like this:

var element = document.getElementById("scroll");
element.scrollIntoView();

This will let you scroll all the way down regards the document height

$('html, body').animate({scrollTop:$(document).height()}, 1000);

My Scenario: I had an list of string, in which I had to append a string given by a user and scroll to the end of the list automatically. I had fixed height of the display of the list, after which it should overflow.

I tried @Jeremy Ruten's answer, it worked, but it was scrolling to the (n-1)th element. If anybody is facing this type of issue, you can use setTimeOut() method workaround. You need to modify the code to below:

setTimeout(() => {
    var objDiv = document.getElementById('div_id');
    objDiv.scrollTop = objDiv.scrollHeight
}, 0)

Here is the StcakBlitz link I have created which shows the problem and its solution : https://stackblitz.com/edit/angular-ivy-x9esw8


smooth scroll with Javascript:

document.getElementById('messages').scrollIntoView({ behavior: 'smooth', block: 'end' });


You can try the code below:

function scrollToBottom (id) {
   var div = document.getElementById(id);
   div.scrollTop = div.scrollHeight - div.clientHeight;
}

To perform a smooth scroll with JQuery:

function scrollSmoothToBottom (id) {
   var div = document.getElementById(id);
   $('#' + id).animate({
      scrollTop: div.scrollHeight - div.clientHeight
   }, 500);
}

See the example on JSFiddle

Here's why this works:

enter image description here

Ref: scrollTop, scrollHeight, clientHeight


Javascript or jquery:

var scroll = document.getElementById('messages');
   scroll.scrollTop = scroll.scrollHeight;
   scroll.animate({scrollTop: scroll.scrollHeight});

Css:

 .messages
 {
      height: 100%;
      overflow: auto;
  }

If you don't want to rely on scrollHeight, the following code helps:

$('#scroll').scrollTop(1000000);

Like you, I'm building a chat app and want the most recent message to scroll into view. This ultimately worked well for me:

//get the div that contains all the messages
let div = document.getElementById('message-container');

//make the last element (a message) to scroll into view, smoothly!
div.lastElementChild.scrollIntoView({ behavior: 'smooth' });

You can use the Element.scrollTo() method.

It can be animated using the built-in browser/OS animation, so it's super smooth.

_x000D_
_x000D_
function scrollToBottom() {
    const scrollContainer = document.getElementById('container');
    scrollContainer.scrollTo({
        top: scrollContainer.scrollHeight,
        left: 0,
        behavior: 'smooth'
    });
}

// initialize dummy content
const scrollContainer = document.getElementById('container');
const numCards = 100;
let contentInnerHtml = '';
for (let i=0; i<numCards; i++) {
  contentInnerHtml += `<div class="card mb-2"><div class="card-body">Card ${i + 1}</div></div>`;
}
scrollContainer.innerHTML = contentInnerHtml;
_x000D_
.overflow-y-scroll {
  overflow-y: scroll;
}
_x000D_
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"/>

<div class="d-flex flex-column vh-100">
  <div id="container" class="overflow-y-scroll flex-grow-1"></div>
  <div>
    <button class="btn btn-primary" onclick="scrollToBottom()">Scroll to bottom</button>
  </div>
</div>
_x000D_
_x000D_
_x000D_


A very simple method to this is to set the scroll to to the height of the div.

var myDiv = document.getElementById("myDiv");
window.scrollTo(0, myDiv.innerHeight);

Scroll to the last element inside the div:

myDiv.scrollTop = myDiv.lastChild.offsetTop

I use the difference between the Y coordinate of the first item div and the Y coordinate of the selected item div. Here is the JavaScript/JQuery code and the html:

_x000D_
_x000D_
function scrollTo(event){
        // In my proof of concept, I had a few <button>s with value 
        // attributes containing strings with id selector expressions
        // like "#item1".
        let selectItem = $($(event.target).attr('value'));
        let selectedDivTop = selectItem.offset().top;

        let scrollingDiv = selectItem.parent();

        let firstItem = scrollingDiv.children('div').first();
        let firstItemTop = firstItem.offset().top;

        let newScrollValue = selectedDivTop - firstItemTop;
        scrollingDiv.scrollTop(newScrollValue);
    }
_x000D_
<div id="scrolling" style="height: 2rem; overflow-y: scroll">
  <div id="item1">One</div>
  <div id="item2">Two</div>
  <div id="item3">Three</div>
  <div id="item4">Four</div>
  <div id="item5">Five</div>
</div>
_x000D_
_x000D_
_x000D_


You can also, using jQuery, attach an animation to html,body of the document via:

$("html,body").animate({scrollTop:$("#div-id")[0].offsetTop}, 1000);

which will result in a smooth scroll to the top of the div with id "div-id".


Javascript or jquery:

var scroll = document.getElementById('messages');
   scroll.scrollTop = scroll.scrollHeight;
   scroll.animate({scrollTop: scroll.scrollHeight});

Css:

 .messages
 {
      height: 100%;
      overflow: auto;
  }

On my Angular 6 application I just did this:

postMessage() {
  // post functions here
  let history = document.getElementById('history')
  let interval    
  interval = setInterval(function() {
    history.scrollTop = history.scrollHeight
    clearInterval(interval)
  }, 1)
}

The clearInterval(interval) function will stop the timer to allow manual scroll top / bottom.


var mydiv = $("#scroll");
mydiv.scrollTop(mydiv.prop("scrollHeight"));

Works from jQuery 1.6

https://api.jquery.com/scrollTop/

http://api.jquery.com/prop/


Scroll to the last element inside the div:

myDiv.scrollTop = myDiv.lastChild.offsetTop

This is much easier if you're using jQuery scrollTop:

$("#mydiv").scrollTop($("#mydiv")[0].scrollHeight);

Just as a bonus snippet. I'm using angular and was trying to scroll a message thread to the bottom when a user selected different conversations with users. In order to make sure that the scroll works after the new data had been loaded into the div with the ng-repeat for messages, just wrap the scroll snippet in a timeout.

$timeout(function(){
    var messageThread = document.getElementById('message-thread-div-id');
    messageThread.scrollTop = messageThread.scrollHeight;
},0)

That will make sure that the scroll event is fired after the data has been inserted into the DOM.


This will let you scroll all the way down regards the document height

$('html, body').animate({scrollTop:$(document).height()}, 1000);

If this is being done for scrolling to the bottom of chat window, do the following

The idea of scrolling to a particular div in the chat was the following

1) Each chat div consisting of Person, time and message is run in a for loop with class chatContentbox

2) querySelectorAll finds all such arrays. It could be 400 nodes (400 chats)

3) go to the last one

4) scrollIntoView()

let lastChatBox = document.querySelectorAll('.chatContentBox'); 
lastChatBox = lastChatBox[lastChatBox.length-1]; 
lastChatBox.scrollIntoView(); 

You can try the code below:

function scrollToBottom (id) {
   var div = document.getElementById(id);
   div.scrollTop = div.scrollHeight - div.clientHeight;
}

To perform a smooth scroll with JQuery:

function scrollSmoothToBottom (id) {
   var div = document.getElementById(id);
   $('#' + id).animate({
      scrollTop: div.scrollHeight - div.clientHeight
   }, 500);
}

See the example on JSFiddle

Here's why this works:

enter image description here

Ref: scrollTop, scrollHeight, clientHeight


alternative solution

function scrollToBottom(element) {
  element.scroll({ top: element.scrollHeight, behavior: 'smooth' });
}

Just as a bonus snippet. I'm using angular and was trying to scroll a message thread to the bottom when a user selected different conversations with users. In order to make sure that the scroll works after the new data had been loaded into the div with the ng-repeat for messages, just wrap the scroll snippet in a timeout.

$timeout(function(){
    var messageThread = document.getElementById('message-thread-div-id');
    messageThread.scrollTop = messageThread.scrollHeight;
},0)

That will make sure that the scroll event is fired after the data has been inserted into the DOM.


var mydiv = $("#scroll");
mydiv.scrollTop(mydiv.prop("scrollHeight"));

Works from jQuery 1.6

https://api.jquery.com/scrollTop/

http://api.jquery.com/prop/


You can use the HTML DOM scrollIntoView Method like this:

var element = document.getElementById("scroll");
element.scrollIntoView();

You can also, using jQuery, attach an animation to html,body of the document via:

$("html,body").animate({scrollTop:$("#div-id")[0].offsetTop}, 1000);

which will result in a smooth scroll to the top of the div with id "div-id".


You can use the Element.scrollTo() method.

It can be animated using the built-in browser/OS animation, so it's super smooth.

_x000D_
_x000D_
function scrollToBottom() {
    const scrollContainer = document.getElementById('container');
    scrollContainer.scrollTo({
        top: scrollContainer.scrollHeight,
        left: 0,
        behavior: 'smooth'
    });
}

// initialize dummy content
const scrollContainer = document.getElementById('container');
const numCards = 100;
let contentInnerHtml = '';
for (let i=0; i<numCards; i++) {
  contentInnerHtml += `<div class="card mb-2"><div class="card-body">Card ${i + 1}</div></div>`;
}
scrollContainer.innerHTML = contentInnerHtml;
_x000D_
.overflow-y-scroll {
  overflow-y: scroll;
}
_x000D_
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"/>

<div class="d-flex flex-column vh-100">
  <div id="container" class="overflow-y-scroll flex-grow-1"></div>
  <div>
    <button class="btn btn-primary" onclick="scrollToBottom()">Scroll to bottom</button>
  </div>
</div>
_x000D_
_x000D_
_x000D_


Using jQuery, scrollTop is used to set the vertical position of scollbar for any given element. there is also a nice jquery scrollTo plugin used to scroll with animation and different options (demos)

var myDiv = $("#div_id").get(0);
myDiv.scrollTop = myDiv.scrollHeight;

if you want to use jQuery's animate method to add animation while scrolling down, check the following snippet:

var myDiv = $("#div_id").get(0);
myDiv.animate({
    scrollTop: myDiv.scrollHeight
  }, 500);

I use the difference between the Y coordinate of the first item div and the Y coordinate of the selected item div. Here is the JavaScript/JQuery code and the html:

_x000D_
_x000D_
function scrollTo(event){
        // In my proof of concept, I had a few <button>s with value 
        // attributes containing strings with id selector expressions
        // like "#item1".
        let selectItem = $($(event.target).attr('value'));
        let selectedDivTop = selectItem.offset().top;

        let scrollingDiv = selectItem.parent();

        let firstItem = scrollingDiv.children('div').first();
        let firstItemTop = firstItem.offset().top;

        let newScrollValue = selectedDivTop - firstItemTop;
        scrollingDiv.scrollTop(newScrollValue);
    }
_x000D_
<div id="scrolling" style="height: 2rem; overflow-y: scroll">
  <div id="item1">One</div>
  <div id="item2">Two</div>
  <div id="item3">Three</div>
  <div id="item4">Four</div>
  <div id="item5">Five</div>
</div>
_x000D_
_x000D_
_x000D_


Newer method that works on all current browsers:

this.scrollIntoView(false);

If this is being done for scrolling to the bottom of chat window, do the following

The idea of scrolling to a particular div in the chat was the following

1) Each chat div consisting of Person, time and message is run in a for loop with class chatContentbox

2) querySelectorAll finds all such arrays. It could be 400 nodes (400 chats)

3) go to the last one

4) scrollIntoView()

let lastChatBox = document.querySelectorAll('.chatContentBox'); 
lastChatBox = lastChatBox[lastChatBox.length-1]; 
lastChatBox.scrollIntoView(); 

A very simple method to this is to set the scroll to to the height of the div.

var myDiv = document.getElementById("myDiv");
window.scrollTo(0, myDiv.innerHeight);

I have encountered the same problem, but with an additional constraint: I had no control over the code that appended new elements to the scroll container. None of the examples I found here allowed me to do just that. Here is the solution I ended up with .

It uses Mutation Observers (https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver) which makes it usable only on modern browsers (though polyfills exist)

So basically the code does just that :

var scrollContainer = document.getElementById("myId");

// Define the Mutation Observer
var observer = new MutationObserver(function(mutations) {

  // Compute sum of the heights of added Nodes
  var newNodesHeight = mutations.reduce(function(sum, mutation) {
      return sum + [].slice.call(mutation.addedNodes)
        .map(function (node) { return node.scrollHeight || 0; })
        .reduce(function(sum, height) {return sum + height});
  }, 0);

  // Scroll to bottom if it was already scrolled to bottom
  if (scrollContainer.clientHeight + scrollContainer.scrollTop + newNodesHeight + 10 >= scrollContainer.scrollHeight) {
    scrollContainer.scrollTop = scrollContainer.scrollHeight;
  }

});

// Observe the DOM Element
observer.observe(scrollContainer, {childList: true});

I made a fiddle to demonstrate the concept : https://jsfiddle.net/j17r4bnk/


On my Angular 6 application I just did this:

postMessage() {
  // post functions here
  let history = document.getElementById('history')
  let interval    
  interval = setInterval(function() {
    history.scrollTop = history.scrollHeight
    clearInterval(interval)
  }, 1)
}

The clearInterval(interval) function will stop the timer to allow manual scroll top / bottom.


Like you, I'm building a chat app and want the most recent message to scroll into view. This ultimately worked well for me:

//get the div that contains all the messages
let div = document.getElementById('message-container');

//make the last element (a message) to scroll into view, smoothly!
div.lastElementChild.scrollIntoView({ behavior: 'smooth' });

small addendum: scrolls only, if last line is already visible. if scrolled a tiny bit, leaves the content where it is (attention: not tested with different font sizes. this may need some adjustments inside ">= comparison"):

var objDiv = document.getElementById(id);
var doScroll=objDiv.scrollTop>=(objDiv.scrollHeight-objDiv.clientHeight);                   

// add new content to div
$('#' + id ).append("new line at end<br>"); // this is jquery!

// doScroll is true, if we the bottom line is already visible
if( doScroll) objDiv.scrollTop = objDiv.scrollHeight;

use :

var element= $('element');
var maxScrollTop = element[0].scrollHeight - element.outerHeight();
element.scrollTop(maxScrollTop);

or check scroll to bottom :

    var element = $(element);
    var maxScrollTop = element[0].scrollHeight - element.outerHeight();
    element.on('scroll', function() {
        if ( element.scrollTop() >= maxScrollTop ) {
            alert('scroll to bottom');
        }
    });

Found this really helpful, thank you.

For the Angular 1.X folks out there:

angular.module('myApp').controller('myController', ['$scope', '$document',
  function($scope, $document) {

    var overflowScrollElement = $document[0].getElementById('your_overflow_scroll_div');
    overflowScrollElement[0].scrollTop = overflowScrollElement[0].scrollHeight;

  }
]);

Just because the wrapping in jQuery elements versus HTML DOM elements gets a little confusing with angular.

Also for a chat application, I found making this assignment after your chats were loaded to be useful, you also might need to slap on short timeout as well.


small addendum: scrolls only, if last line is already visible. if scrolled a tiny bit, leaves the content where it is (attention: not tested with different font sizes. this may need some adjustments inside ">= comparison"):

var objDiv = document.getElementById(id);
var doScroll=objDiv.scrollTop>=(objDiv.scrollHeight-objDiv.clientHeight);                   

// add new content to div
$('#' + id ).append("new line at end<br>"); // this is jquery!

// doScroll is true, if we the bottom line is already visible
if( doScroll) objDiv.scrollTop = objDiv.scrollHeight;

I have encountered the same problem, but with an additional constraint: I had no control over the code that appended new elements to the scroll container. None of the examples I found here allowed me to do just that. Here is the solution I ended up with .

It uses Mutation Observers (https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver) which makes it usable only on modern browsers (though polyfills exist)

So basically the code does just that :

var scrollContainer = document.getElementById("myId");

// Define the Mutation Observer
var observer = new MutationObserver(function(mutations) {

  // Compute sum of the heights of added Nodes
  var newNodesHeight = mutations.reduce(function(sum, mutation) {
      return sum + [].slice.call(mutation.addedNodes)
        .map(function (node) { return node.scrollHeight || 0; })
        .reduce(function(sum, height) {return sum + height});
  }, 0);

  // Scroll to bottom if it was already scrolled to bottom
  if (scrollContainer.clientHeight + scrollContainer.scrollTop + newNodesHeight + 10 >= scrollContainer.scrollHeight) {
    scrollContainer.scrollTop = scrollContainer.scrollHeight;
  }

});

// Observe the DOM Element
observer.observe(scrollContainer, {childList: true});

I made a fiddle to demonstrate the concept : https://jsfiddle.net/j17r4bnk/


Java Script:

document.getElementById('messages').scrollIntoView(false);

Scrolls to the last line of the content present.


Sometimes the most simple is the best solution: I do not know if this will help, it helped me to scroll it were ever I wanted too. The higher the "y=" is,the more down it scrolls and of course "0" means top, so there for example "1000" could be bottom, or "2000" or "3000" and so on, depending how long your page is. This usually works in a button with onclick or onmouseover.

window.scrollTo(x=0,y=150);

Set the distance from the top of the scrollable element to be the total height of the element.

const element = this.shadowRoot.getElementById('my-scrollable-div')
element.scrollTop = element.scrollHeight

using jQuery animate:

$('#DebugContainer').stop().animate({
  scrollTop: $('#DebugContainer')[0].scrollHeight
}, 800);

Sometimes the most simple is the best solution: I do not know if this will help, it helped me to scroll it were ever I wanted too. The higher the "y=" is,the more down it scrolls and of course "0" means top, so there for example "1000" could be bottom, or "2000" or "3000" and so on, depending how long your page is. This usually works in a button with onclick or onmouseover.

window.scrollTo(x=0,y=150);

My Scenario: I had an list of string, in which I had to append a string given by a user and scroll to the end of the list automatically. I had fixed height of the display of the list, after which it should overflow.

I tried @Jeremy Ruten's answer, it worked, but it was scrolling to the (n-1)th element. If anybody is facing this type of issue, you can use setTimeOut() method workaround. You need to modify the code to below:

setTimeout(() => {
    var objDiv = document.getElementById('div_id');
    objDiv.scrollTop = objDiv.scrollHeight
}, 0)

Here is the StcakBlitz link I have created which shows the problem and its solution : https://stackblitz.com/edit/angular-ivy-x9esw8


Set the distance from the top of the scrollable element to be the total height of the element.

const element = this.shadowRoot.getElementById('my-scrollable-div')
element.scrollTop = element.scrollHeight

This is much easier if you're using jQuery scrollTop:

$("#mydiv").scrollTop($("#mydiv")[0].scrollHeight);

alternative solution

function scrollToBottom(element) {
  element.scroll({ top: element.scrollHeight, behavior: 'smooth' });
}

Newer method that works on all current browsers:

this.scrollIntoView(false);

Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to html

Embed ruby within URL : Middleman Blog Please help me convert this script to a simple image slider Generating a list of pages (not posts) without the index file Why there is this "clear" class before footer? Is it possible to change the content HTML5 alert messages? Getting all files in directory with ajax DevTools failed to load SourceMap: Could not load content for chrome-extension How to set width of mat-table column in angular? How to open a link in new tab using angular? ERROR Error: Uncaught (in promise), Cannot match any routes. URL Segment

Examples related to ajax

Getting all files in directory with ajax Cross-Origin Read Blocking (CORB) Jquery AJAX: No 'Access-Control-Allow-Origin' header is present on the requested resource Fetch API request timeout? How do I post form data with fetch api? Ajax LARAVEL 419 POST error Laravel 5.5 ajax call 419 (unknown status) How to allow CORS in react.js? Angular 2: How to access an HTTP response body? How to post a file from a form with Axios

Examples related to chat

Automatically scroll down chat div Android Whatsapp/Chat Examples Change color of Label in C# Best way to store chat messages in a database? Scroll to bottom of div?