Weird Thoughts From Eric's Head

Categories : All | AJAX | BUSINESS | PERSONAL | PROGRAMMING | BOOK REVIEW

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


Thanks for the code. It helps me for my chat program.
You don't know how long i've been looking for this code, thanks!
thank you, this code made my day
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>
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;
Thanks for this code, I'll also be using it in my AJAX chat program
actually, you dont need to do objDiv.scrollTop = 0-objDiv.scrollHeight; just objDiv.scrollTop = 0;
How did you get the scrollbar to appear? Please forgive me for the "newbie" question.
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
Awesome. I was looking for the answer to this question.
For DIV it's working properly. But not working for SELECT TAG. I wnat for this.
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');
It is not going to work with a select tag since that is a different type of element. Eric
Thanks. I've been looking all day for a way to do this.
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?
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>
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
I was looking for this exact solution for my asp.net chat program. Works flawlessly. Thanks.
Yep, this is invaluable knowledge. If only it came with the wisdom to use it only for good, and not for evil... oh well, at least I'm having fun.
thanks, this is just what i needed :)
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!
Great code, but unfortunaly doesn't works in Opera :/
Works fine in my version of Opera 8.5. Eric
3. line in code should be:
if(test1>test2)
Also it could be more optimised.
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.
thank you very much, this is what exactly i was looking for
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>">
Thanks !This two line code has really solved my problem.
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?
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.
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.

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?

THX very much, You helped me a lot! This works also on Opera 9 beta as I checked.
Thanks, this's very helpful!
Cheers dude - I wasted an hour before I found this page!
how can you determine user interaction and sto pscrolling?
Perfect. Makes a mockery of other sites who insist on 100 lines of code, mostly completely irrelevant. Thanks.
simple and nice.. thnx :) really helpful in my project
sorry, this code not works with explorer , i tried two divs inner and outer but doesn't work. please i need help
Thanks for sharing. This has been very useful.
Thanks Eric. Just what I needed for my chat app. X Graham
simple and nice.. helpful
Ahmet Kaymaz
www.ahmetkaymaz.com
C# SQL Server AJAX
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!
sounds like you are calling it before you add the item and not after to me.
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?
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.
Fisher, Talked about it before: http://radio.javaranch.com/pascarello/2005/07/18/1121709316718.html Eric
Jackson, did you look at the link that says Update in bold letters at the top. That version does it.
Sorry, I had not seen it. Many thanks
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 - 270
So 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
}
Thanks Ryan! Although instead of hard-coding the height of the div, you can try using e.offsetHeight. Works for me anyway.
Thank you. I've been looking for this. man0815
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.


Add a comment

Title
Body
HTML : b, i, blockquote, br, p, pre, a href="", ul, ol, li
Math Quiz 6 + 6 = (Helps stop blog spam)
Name
E-mail address
Website
Remember me Yes  No 

E-mail addresses are not publicly displayed, so please only leave your e-mail address if you would like to be notified when new comments are added to this blog entry (you can opt-out later).

TrackBack to http://radio.javaranch.com/pascarello/addTrackBack.action?entry=1134573598403