JavaScript: Scroll to Bottom of a Div
UPDATE: check out the new version here: Allow user to scroll and maintain position with "Scroll To Bottom of the Div" example
I have seen the question asked on how do I scroll a div to the bottom for my Ajax based chat/ log/ news grabber/ etc. It is rather easy to do and involves a little bit of code utilizing scrollTop and scrollHeight.
var objDiv = document.getElementById("divExample");
objDiv.scrollTop = objDiv.scrollHeight;
Now if you have not noticed, the div below has been updating the time and it scroll position is at the bottom. Of course you would have to code some fancy stuff in it to take into account if the user has moved it and is reading it. I will leave it up to you to figure that out.
Hope that helps you out a little!
Eric Pascarello
Coauthor of Ajax In Action
Moderator of HTML/JavaScript at www.JavaRanch.com
Author of: JavaScript: Your Visual Blueprint for Dynamic Web Pages
TrackBacks[0]
Comments[53]
Posted by pascarello on December 14, 2005 10:19:58 AM EST
Reply |
Permalink
Re: JavaScript: Scroll to Bottom of a Div
Thanks for the code. It helps me for my chat program.
Comment from Anonymous on December 20, 2005 3:55:07 PM EST
You don't know how long i've been looking for this code, thanks!
Comment from BasDV on October 1, 2006 2:56:52 AM EST
thank you, this code made my day
Comment from emoo on January 30, 2007 3:50:30 AM EST
Hi I am trying to create a chat support feature for my website. when you enter text into the div the scroll bar will not go down and you have to manually scroll every time. Below is my code any suggestions please?
<html> <head> <title>3d Chat</title> <script src="prototype.js" type="text/javascript"></script>
<link href="main.css" media="screen" rel="Stylesheet" type="text/css">
<link href="nav.css" media="screen" rel="Stylesheet" type="text/css"> <link href="store.css" media="screen" rel="Stylesheet" type="text/css"> </head>
<body> <Script Language=JavaScript> var n = 0; var currPos = 0; var newPos = 1; var isDiv = ""; function startScroll(){ if (newPos > currPos){ currPos = isDiv.scrollTop; isDiv.scrollTop = 500; newPos = isDiv.scrollTop; startScroll(); } } function toBottom(){ isDiv = document.getElementById('div1'); isDiv.scrollTop = 0; startScroll(); } window.onload=toBottom; </Script> <div id="chatwrapper"> <!-- Wrapper div to avoid IE double margin bug --> <div style="width=375px"> <div id="chatcontent"> <div class="headingLeft"><div class="headingRight">Live Chat</div></div> <div class="box"> <div id="div1 style="overflow: auto; height: 70px"> <p style="color: #458B00">Please wait, one of our representatives will be with you shortly... </div>
<form name="chatForm" method="post" onSubmit="new Ajax.Updater('div1', 'update_chat.html', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;"> <textarea cols=30 rows=4 name=chat></textarea>
<input type=submit name=submit value="Send Message"> </form> </div> </div> </div> </div> </div> </body> </html>
<html> <head> <title>3d Chat</title> <script src="prototype.js" type="text/javascript"></script>
<link href="main.css" media="screen" rel="Stylesheet" type="text/css">
<link href="nav.css" media="screen" rel="Stylesheet" type="text/css"> <link href="store.css" media="screen" rel="Stylesheet" type="text/css"> </head>
<body> <Script Language=JavaScript> var n = 0; var currPos = 0; var newPos = 1; var isDiv = ""; function startScroll(){ if (newPos > currPos){ currPos = isDiv.scrollTop; isDiv.scrollTop = 500; newPos = isDiv.scrollTop; startScroll(); } } function toBottom(){ isDiv = document.getElementById('div1'); isDiv.scrollTop = 0; startScroll(); } window.onload=toBottom; </Script> <div id="chatwrapper"> <!-- Wrapper div to avoid IE double margin bug --> <div style="width=375px"> <div id="chatcontent"> <div class="headingLeft"><div class="headingRight">Live Chat</div></div> <div class="box"> <div id="div1 style="overflow: auto; height: 70px"> <p style="color: #458B00">Please wait, one of our representatives will be with you shortly... </div>
<form name="chatForm" method="post" onSubmit="new Ajax.Updater('div1', 'update_chat.html', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;"> <textarea cols=30 rows=4 name=chat></textarea>
<input type=submit name=submit value="Send Message"> </form> </div> </div> </div> </div> </div> </body> </html>
Comment from Jamie on March 13, 2007 11:04:16 AM EST
Thanks so much! Just implemented on Streampad (http://www.streampad.com). I actually needed to scroll to the top of a div, so subtracted from 0:
var objDiv = document.getElementById("divExample");
objDiv.scrollTop = 0-objDiv.scrollHeight;
Comment from dan on December 22, 2005 11:51:25 AM EST
Thanks for this code, I'll also be using it in my AJAX chat program
Comment from Ryan Smith on December 22, 2005 12:24:00 PM EST
actually, you dont need to do
objDiv.scrollTop = 0-objDiv.scrollHeight;
just
objDiv.scrollTop = 0;
Comment from dan on December 22, 2005 2:06:37 PM EST
How did you get the scrollbar to appear?
Please forgive me for the "newbie" question.
Comment from Dave on December 22, 2005 8:08:40 PM EST
div with a set height and scroll set to auto make a scrollbar appear. Do a view source on the page to see the code.
Eric
Eric
Comment from Eric Pascarello on December 22, 2005 11:22:47 PM EST
Awesome. I was looking for the answer to this question.
Comment from thekidder on January 17, 2006 9:35:00 PM EST
For DIV it's working properly.
But not working for SELECT TAG.
I wnat for this.
Comment from Anonymous on January 31, 2006 5:22:30 AM EST
I kind of did it, it's maybe a hack tough it works for me, please test yourselves and let me know:
function forceScrollBottom(divName)
{
mydiv = document.getElementById(divName);
//var debug = "ScrollTop: " + mydiv.scrollTop;
for (i = 50; i < mydiv.scrollHeight; i += 50)
{
var tmp = mydiv.scrollTop;
// pre-store scrollTop
mydiv.scrollTop += i;
// update scrollTop
if (tmp == mydiv.scrollTop)
{
break;
}
//debug += i + "ScrollTop: " + mydiv.scrollTop + "\n";
}
//alert(debug);
}
forceScrollBottom('sampleDiv');
{
mydiv = document.getElementById(divName);
//var debug = "ScrollTop: " + mydiv.scrollTop;
for (i = 50; i < mydiv.scrollHeight; i += 50)
{
var tmp = mydiv.scrollTop;
// pre-store scrollTop
mydiv.scrollTop += i;
// update scrollTop
if (tmp == mydiv.scrollTop)
{
break;
}
//debug += i + "ScrollTop: " + mydiv.scrollTop + "\n";
}
//alert(debug);
}
forceScrollBottom('sampleDiv');
Comment from Diegocbapp on November 23, 2006 11:08:33 PM EST
It is not going to work with a select tag since that is a different type of element.
Eric
Comment from Eric Pascarello on January 31, 2006 9:52:54 AM EST
Thanks. I've been looking all day for a way to do this.
Comment from Anonymous on January 31, 2006 10:32:14 AM EST
Hi, thanks for this.
However, it works perfectly in Geko browsers, scrolling to the bottom of the div, however, in IE, it only scrolls part way down.
Is there any way to fix this?
Comment from Matt on February 19, 2006 5:43:34 AM EST
in i.e. you have to create an inner div for the content and set the inner div's scrollTop to 0.
example:
<div id="outer_div" style="height:100px;overflow:auto;">
<div id="inner_div">
content... content...
</div>
</div>
Comment from Anonymous on February 27, 2006 8:42:57 AM EST
reset the scrollTop first by setting it to 0 (zero) and then set it back again to scrollHeight
element.scrollTop = 0;
element.scrollTop = element.scrollHeight;
that should fix IE's problem
Comment from Anonymous on December 4, 2006 1:20:58 PM EST
I was looking for this exact solution for my asp.net chat program. Works flawlessly. Thanks.
Comment from Bryan on February 28, 2006 4:39:00 PM EST
thanks, this is just what i needed :)
Comment from Morlhach on March 17, 2006 6:40:07 AM EST
I never knew you could set the value of scrollTop. I thought it was only read-only (get). Thanks, this helped me a lot. Cheers!
Comment from Alex2 on March 24, 2006 4:40:02 AM EST
Great code, but unfortunaly doesn't works in Opera :/
Comment from deni2s on March 27, 2006 2:18:05 PM EST
Works fine in my version of Opera 8.5.
Eric
Comment from Eric Pascarello on March 27, 2006 3:15:39 PM EST
3. line in code should be:
if(test1>test2)Also it could be more optimised.
Comment from deni2s on March 27, 2006 3:47:37 PM EST
Ok, i had a problem with css. But on the net I found also something like this:
var test1 = objDiv.scrollHeight;
var test2 = objDiv.offsetHeight;
if (test1 > 0) // all but Explorer Mac
{
objDiv.scrollTop = objDiv.scrollHeight;
}
else // Explorer Mac;
//would also work in Explorer 6 Strict, Mozilla and Safari
{
objDiv.scrollTop = objDiv.offsetHeight;
}
Looks like it's more cross browser compatible.
Comment from deni2s on March 27, 2006 3:48:18 PM EST
thank you very much, this is what exactly
i was looking for
Comment from vak on April 10, 2006 1:09:58 AM EST
Damned, doesn't work at my IE 6.0.29 :(
I use the following
<div style="overflow: auto; height: 40px; width: 100%; padding: 2px; background: none; background-color: ##000000; border: none; color: ##FFFFFF; font-family: 'Courier New', Courier, mono;" id="commandlog" cols="82" rows="16">#Session.commandLog#</div>## is because it's ColdFusion script
<cfset Session.commandLog = Session.commandLog & "<div><a name=""#Session.commandCount#"" style=""text-decoration: none; color: ##FFFFFF;"">Command ##" & Session.commandCount & " : " & DateFormat(getJobID.time_issued, "dd mmm yyyy") & " " & TimeFormat(getJobID.time_issued, "HH:mm:ss") & " -> " & form.command & "</div>">
Comment from Sasha on May 5, 2006 6:51:01 AM EST
Thanks !This two line code has really solved my problem.
Comment from tahir niazi on May 11, 2006 8:19:48 AM EST
Slight problem, I have it working fine in MSIE and FF, but it doesn't want to work in Opera. I'm using two divs, id="mainright" is the outer one, and the inner one has no id.
document.getElementById('mainright').scrollTop += 10;
Any ideas why it might not be working?
Comment from Joe on May 18, 2006 2:25:04 PM EST
Great tips and great replies..
Would you mind telling me how to control the vertical scrollbars in DIV?
For example, I want to alert a message when the vertical scrollbars reaches the bottom.
Comment from Eddie on May 26, 2006 8:01:28 AM EST
Sorry, I'm having problems with controlling the vertical srcollbar in DIV.
I want to alert a message when the vertical scrollbar I'm scrolling reaches the bottom.
Thanks.
Comment from Eddies on May 26, 2006 8:08:30 AM EST
It doesn't work in Opera (even 8.5) if there is no
overflow: auto;or
overflow: scroll;in style attribute.
Has anybody any idea how to scroll to bottom of a Div element which has
overflow: hidden;in its style attribiute?
Comment from Wojtek Zielinski on May 31, 2006 8:06:41 AM EST
THX very much, You helped me a lot!
This works also on Opera 9 beta as I checked.
Comment from Thinker[PL] on June 5, 2006 3:24:40 PM EST
Thanks, this's very helpful!
Comment from Binh on June 23, 2006 12:09:27 PM EST
Cheers dude - I wasted an hour before I found this page!
Comment from Dave on July 23, 2006 4:35:28 PM EST
how can you determine user interaction and sto pscrolling?
Comment from ceco on July 27, 2006 11:48:00 AM EST
Perfect.
Makes a mockery of other sites who insist on 100 lines of code, mostly completely irrelevant.
Thanks.
Comment from gp on August 22, 2006 10:41:22 AM EST
simple and nice.. thnx :) really helpful in my project
Comment from szpilman on October 18, 2006 10:56:44 AM EST
sorry, this code not works with explorer , i tried two divs inner and outer but doesn't work. please i need help
Comment from shasha on October 30, 2006 5:21:39 AM EST
Thanks for sharing.
This has been very useful.
Comment from Anonymous on November 27, 2006 6:19:13 AM EST
Thanks Eric.
Just what I needed for my chat app. X
Graham
Comment from Graham on December 18, 2006 2:23:15 PM EST
Comment from Ahmet Kaymaz on December 22, 2006 2:27:28 AM EST
Thanks for this. Usefull for my chat app but yes, it scrolls to the bottom but not totally because the last message is not visible. I need to scroll one click to see it.
Here is my div:
<div id="divMsg" class="divMsg"> </div>
.divMsg
{
border: 1px solid #555555;
background-color:#FFFFFF;
height:200px;
overflow:auto;
}
Thanks!
Comment from Daniel on January 2, 2007 10:06:53 AM EST
sounds like you are calling it before you add the item and not after to me.
Comment from Eric Pascarello on January 2, 2007 5:53:12 PM EST
sorry to ask stupid qustion here. i am really new in coldfusion.
may i know, how to i the scroll position after postback?
i have a long table with many textarea, i would like to submit the text and save them into DB. so after save(screen refresh) how do i keep the screen stay with the my previouse updated textarea instead of top of the page?
Comment from Fisher on January 4, 2007 5:44:56 AM EST
Thank you so much. It was exactly what I was looking for. I haven't figured out how to determine whether the user has moved the scroll bar to look at read something or not. I tried comparing scrollTop and scrollHeight before I make any changes to the content but to no avail yet. If anyone figures it out, I could use the help.
Comment from Jackson on January 4, 2007 7:05:03 PM EST
Fisher,
Talked about it before:
http://radio.javaranch.com/pascarello/2005/07/18/1121709316718.html
Eric
Comment from Eric Pascarello on January 4, 2007 11:16:39 PM EST
Jackson, did you look at the link that says Update in bold letters at the top. That version does it.
Comment from Eric Pascarello on January 4, 2007 11:18:11 PM EST
Sorry, I had not seen it. Many thanks
Comment from Jackson on January 4, 2007 11:22:21 PM EST
Great code there- Just beware that when you set the scrollTop = scrollHeight, you are actually setting scrollTop to a value greater than the maximum scrollTop value. The maximum scrollTop is actually the scrollHeight MINUS the height of the div. So in this case, if your scrolling div is 270 pixels in height, these two statements produce the same result:
e.scrollTop = e.scrollHeight e.scrollTop = e.scrollHeight - 270So anyways, here's a little addition to the code above for "pinning" the scrollbar to the bottom, but only when the user has not previously scrolled up from the bottom manually. The number "270" in the code below is the height of the scolling div element in pixels. Note that calling "e.style.height" will not work without manipulation, because that will return the contents of the div tag's height attribute in a css format like "270px" or "100%" so you have to either hard-code the height in or manipulate/cleanse the return value of the height attribute lookup. Anyways, here's the code-
e = document.getElementById('myDiv')
//set your "pin" variable to false by default
var blnPinScrollbar = false
//if the scrollbar is at the very
//bottom before updating the div,
//then set the pin variable to true
if(e.scrollTop == (e.scrollHeight - 270)){
blnPinScrollbar = true
}
//alert("blnPinScrollbar=" + blnPinScrollbar + "(" + e.scrollTop + "=" + e.scrollHeight + "-" + e.style.height + ")")
//Set the new content in the div.
e.innerHTML = newbuffer
//if the pin variable is true,
//go ahead and scroll down,
//otherwise, don't touch the
//scroll position
if(blnPinScrollbar){
e.scrollTop = e.scrollHeight
}
Comment from Ryan Cooper on January 8, 2007 2:46:27 PM EST
Thanks Ryan!
Although instead of hard-coding the height of the div, you can try using e.offsetHeight. Works for me anyway.
Comment from James on March 7, 2007 7:50:16 AM EST
Thank you. I've been looking for this.
man0815
Comment from Anonymous on March 28, 2007 1:24:25 PM EST
Thank you. This works without the scrollbars, too, which will allow us to place chat from Second Life on our website and make it look like the visitor's actually in the virtual world.
Comment from Ben Faust on April 11, 2007 2:36:08 PM EST
TrackBack to http://radio.javaranch.com/pascarello/addTrackBack.action?entry=1134573598403