PDA

View Full Version : synchronized textarea scrollbars



kencl
08-19-2006, 12:37 AM
Hi Folks,

I saw a script a while back which allowed you to synchronize the position of the scrollbars between two textareas. Both textareas contained the same number of lines, containing two related lists, so it was very nice to be able to scroll one and have the second keep the alignment between the two.

Anyone know where this script might be? Ok, that's a long shot, but if not, how would you go about starting to write something like that? I hate having to reinvent the wheel, but I can't find this one in my script library...:(

mburt
08-19-2006, 12:53 AM
I think this is what you're talking about.

When you scroll the first div, it scrolls the second, and vice-versa.


<html>
<head>
<style type="text/css">
.content {
height:100px;
width:150px;
overflow-y:scroll;
padding:2px;
border:1px solid black;
float:left
}
</style>
</head>
<body>
<div class="content" id="first" onscroll="second.scrollTop=scrollTop">
Line
<br>Line
<br>Line
<br>Line
<br>Line
<br>Line
<br>Line
<br>Line
<br>Line
<br>Line
<br>Line
<br>Line
<br>Line
</div>
<div class="content" id="second" onscroll="first.scrollTop=scrollTop">
Line
<br>Line
<br>Line
<br>Line
<br>Line
<br>Line
<br>Line
<br>Line
<br>Line
<br>Line
<br>Line
<br>Line
<br>Line
</div>
</body>
</html>

kencl
08-19-2006, 01:00 AM
Yep, that's the behavior exactly. However, I need to apply it to textareas so the user can modify the lists.

mburt
08-19-2006, 01:06 AM
Simple: Just remove any html within the divinsion and rename the <div> tags to <textarea>

Look here:

<html>
<head>
<style type="text/css">
.content {
height:100px;
width:150px;
overflow-y:scroll;
padding:2px;
border:1px solid black;
float:left
}
</style>
</head>
<body>
<textarea class="content" id="first" onscroll="second.scrollTop=scrollTop">
Line
Line
Line
Line
Line
Line
Line
Line
Line
Line
Line
Line
Line
Line
Line
Line
</textarea>
<textarea class="content" id="second" onscroll="first.scrollTop=scrollTop">
Line
Line
Line
Line
Line
Line
Line
Line
Line
Line
Line
Line
Line
Line
Line
Line
</textarea>
</body>
</html>

kencl
08-19-2006, 01:15 AM
Yeah, seeing your first answer, that's exactly what I tried. Works in IE after "allowing blocked content", and not in FireFox at all. Too bad. The div version works in both without warnings...:confused:

Thanks for the idea though. I may still use it and just tell my client to use IE and enable active content on that page...

mburt
08-19-2006, 04:04 AM
Or!! (insert dramatic music here)

add this to the div tags:


...<div contenteditable>

It makes the divinsions editable

shachi
08-19-2006, 07:20 AM
Here, this must work in firefox not sure about IE, test it though.:)



<html>
<head>
<script type="text/javascript">
function scrolltheother(){
var farea = document.testform.testarea;
var sarea = document.testform.stestarea;
sarea.scrollTop = farea.scrollTop;
setTimeout("scrolltheother()",10);
}
window.onload = scrolltheother;
</script>
</head>
<body>
<form name="testform">
<textarea cols="30" rows="10" id="fArea" name="testarea" onscroll="scrolltheother()">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Fusce luctus turpis. Proin a lacus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed non purus in tellus semper porta. Praesent vel quam nec orci mollis dignissim. Nulla ultrices, tellus quis semper pretium, eros augue eleifend risus, at dictum massa urna blandit metus. Nullam libero metus, scelerisque in, sollicitudin in, tristique nec, tortor. Sed eu felis. Integer rutrum mauris id nisl. Praesent cursus. Vivamus faucibus.

Suspendisse erat enim, interdum et, semper quis, luctus ut, tortor. Sed sodales. Cras lacus. Quisque laoreet, orci ac imperdiet congue, quam odio malesuada magna, eu vulputate diam sapien vitae magna. Maecenas dictum imperdiet nulla. Sed interdum ipsum a massa. Quisque dictum. Sed pede nibh, nonummy sed, imperdiet et, ullamcorper ac, neque. Maecenas sollicitudin lacinia neque. Nunc neque quam, cursus ut, lacinia vitae, luctus eget, lacus. Proin vestibulum augue eu pede. Maecenas eu sapien. Vivamus quis ipsum nec nunc cursus accumsan.

Sed ac lectus ac metus pulvinar vehicula. Donec ut tortor. Donec pulvinar velit in quam posuere sollicitudin. Nullam laoreet mi. Sed nonummy, augue sit amet hendrerit placerat, mauris orci condimentum risus, placerat fermentum tellus turpis a velit. In hac habitasse platea dictumst. Nullam gravida, tortor vel tempor euismod, risus massa iaculis nulla, sagittis tincidunt sem justo quis quam. Nulla metus augue, ornare eget, sagittis ac, commodo quis, ipsum. Donec non sem iaculis tellus interdum hendrerit. Curabitur velit augue, ultrices id, vehicula sed, pulvinar eu, est. Vestibulum nonummy varius dolor. Aenean vel lacus eget sem suscipit bibendum. Aliquam facilisis, orci id sodales consequat, nisl tortor egestas justo, eget venenatis dui massa sit amet dolor. Cras dui odio, sodales id, ullamcorper sed, molestie vitae, turpis.

Sed ipsum quam, vehicula quis, iaculis nec, tempus at, enim. Cras ac nisl id nunc bibendum scelerisque. Vestibulum interdum, enim non feugiat pulvinar, metus urna aliquam tortor, adipiscing bibendum nibh nisi sed metus. Pellentesque pede. Sed dolor. Nullam a ipsum. Quisque quis tellus. Sed tortor leo, porta id, sagittis ac, tristique sit amet, mi. Fusce ornare urna id ipsum. Pellentesque sit amet risus. Morbi ut augue. Mauris sit amet dui. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed a odio. Etiam dignissim, diam in rutrum condimentum, massa lorem placerat dolor, id placerat nisl nisl dignissim lorem. Donec placerat est eget neque.

Ut tincidunt, magna non tincidunt iaculis, odio eros dapibus ipsum, quis mollis erat pede eu libero. Mauris vulputate ipsum non erat. Quisque egestas felis eu metus. Suspendisse turpis. Donec purus neque, sagittis a, rutrum eu, sodales vel, tellus. Praesent dignissim, mi sed interdum sodales, orci diam ultricies lorem, nec imperdiet orci ante eget dui. Integer rutrum augue at urna. Praesent pellentesque. Praesent hendrerit bibendum ipsum. Suspendisse pede sapien, scelerisque ac, rutrum vel, pellentesque quis, nunc. Ut velit. Vestibulum condimentum neque eget nisl. Nulla sodales aliquet orci. Morbi fermentum. Maecenas facilisis ante interdum odio. Proin aliquam semper magna. Praesent tristique diam ut leo. Morbi tristique quam quis ante. Cras ultricies. Donec tortor.
</textarea>
<textarea cols="30" rows="10" id="sArea" name="stestarea">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Fusce luctus turpis. Proin a lacus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed non purus in tellus semper porta. Praesent vel quam nec orci mollis dignissim. Nulla ultrices, tellus quis semper pretium, eros augue eleifend risus, at dictum massa urna blandit metus. Nullam libero metus, scelerisque in, sollicitudin in, tristique nec, tortor. Sed eu felis. Integer rutrum mauris id nisl. Praesent cursus. Vivamus faucibus.

Suspendisse erat enim, interdum et, semper quis, luctus ut, tortor. Sed sodales. Cras lacus. Quisque laoreet, orci ac imperdiet congue, quam odio malesuada magna, eu vulputate diam sapien vitae magna. Maecenas dictum imperdiet nulla. Sed interdum ipsum a massa. Quisque dictum. Sed pede nibh, nonummy sed, imperdiet et, ullamcorper ac, neque. Maecenas sollicitudin lacinia neque. Nunc neque quam, cursus ut, lacinia vitae, luctus eget, lacus. Proin vestibulum augue eu pede. Maecenas eu sapien. Vivamus quis ipsum nec nunc cursus accumsan.

Sed ac lectus ac metus pulvinar vehicula. Donec ut tortor. Donec pulvinar velit in quam posuere sollicitudin. Nullam laoreet mi. Sed nonummy, augue sit amet hendrerit placerat, mauris orci condimentum risus, placerat fermentum tellus turpis a velit. In hac habitasse platea dictumst. Nullam gravida, tortor vel tempor euismod, risus massa iaculis nulla, sagittis tincidunt sem justo quis quam. Nulla metus augue, ornare eget, sagittis ac, commodo quis, ipsum. Donec non sem iaculis tellus interdum hendrerit. Curabitur velit augue, ultrices id, vehicula sed, pulvinar eu, est. Vestibulum nonummy varius dolor. Aenean vel lacus eget sem suscipit bibendum. Aliquam facilisis, orci id sodales consequat, nisl tortor egestas justo, eget venenatis dui massa sit amet dolor. Cras dui odio, sodales id, ullamcorper sed, molestie vitae, turpis.

Sed ipsum quam, vehicula quis, iaculis nec, tempus at, enim. Cras ac nisl id nunc bibendum scelerisque. Vestibulum interdum, enim non feugiat pulvinar, metus urna aliquam tortor, adipiscing bibendum nibh nisi sed metus. Pellentesque pede. Sed dolor. Nullam a ipsum. Quisque quis tellus. Sed tortor leo, porta id, sagittis ac, tristique sit amet, mi. Fusce ornare urna id ipsum. Pellentesque sit amet risus. Morbi ut augue. Mauris sit amet dui. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed a odio. Etiam dignissim, diam in rutrum condimentum, massa lorem placerat dolor, id placerat nisl nisl dignissim lorem. Donec placerat est eget neque.

Ut tincidunt, magna non tincidunt iaculis, odio eros dapibus ipsum, quis mollis erat pede eu libero. Mauris vulputate ipsum non erat. Quisque egestas felis eu metus. Suspendisse turpis. Donec purus neque, sagittis a, rutrum eu, sodales vel, tellus. Praesent dignissim, mi sed interdum sodales, orci diam ultricies lorem, nec imperdiet orci ante eget dui. Integer rutrum augue at urna. Praesent pellentesque. Praesent hendrerit bibendum ipsum. Suspendisse pede sapien, scelerisque ac, rutrum vel, pellentesque quis, nunc. Ut velit. Vestibulum condimentum neque eget nisl. Nulla sodales aliquet orci. Morbi fermentum. Maecenas facilisis ante interdum odio. Proin aliquam semper magna. Praesent tristique diam ut leo. Morbi tristique quam quis ante. Cras ultricies. Donec tortor.
</textarea>
</body>
</html>

jscheuer1
08-19-2006, 06:23 PM
Mozilla's lack of wide support for the onscroll event and Opera's lack of wide support for the scrollTop property make this unlikely to ever be well implemented cross browser very well. The method mburt uses is IE only from the beginning, due to its reliance upon the assumed document.all object which is not supported even in other browsers that support the literal document.all object. It also suffers from excessive styling of the textareas, which renders them unusable in many ways in Opera. Even converted to getElementByID, it lacks portability in that onscroll for textarea is not widely supported. The method used by shachi doesn't even work in FF, as the second area becomes crippled when scrolled (this part could probably be worked out). It also relies on polling, not the best idea, if it can be avoided. I've come up with a method that works well in IE, fairly well in FF (mousewheel scrolling support is jumpy) and not at all in Opera (no support for this use of the scrollTop property for textarea):


<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Sync Scroll - Demo</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<script type="text/javascript">
function syncScroll(el){
if (el.id=='first')
document.getElementById('second').scrollTop=el.scrollTop;
else
document.getElementById('first').scrollTop=el.scrollTop
}
var syncEm=new Function("if(this.filters)this.blur();syncScroll(this)");
onload=function(){
var ids=['first', 'second'];
for (var i_tem = 0; i_tem < ids.length; i_tem++){
var theS=document.getElementById(ids[i_tem])
if (!document.body.filters)
theS.onmousedown=theS.onmouseup=theS.onmousemove=theS.onscroll=theS.onkeyup=syncEm;
else
theS.onscroll=syncEm;
}
}
</script>
</head>
<body>
<textarea rows="6" class="content" id="first">
Line1
Line2
Line3
Line4
Line5
Line6
Line7
Line8
Line9
Line10
Line11
Line12
Line13
Line14
Line15
Line16
</textarea>
<textarea rows="6" class="content" id="second">
Line1
Line2
Line3
Line4
Line5
Line6
Line7
Line8
Line9
Line10
Line11
Line12
Line13
Line14
Line15
Line16
</textarea>
</body>
</html>

Notes: I'm not happy about needing to assign so many events in Mozilla to overcome its scanty support for the onscroll event, there may be a better way.

shachi
08-20-2006, 06:13 AM
jscheuer1: my code does work but the only problem is that the first textarea doesn't get scrolled when the second textarea is scrolled. I was trying to fix it but don't know how.

jscheuer1
08-20-2006, 07:56 AM
jscheuer1: my code does work but the only problem is that the first textarea doesn't get scrolled when the second textarea is scrolled. I was trying to fix it but don't know how.

Well, I did say that part could probably be worked out. However, what it did for me was that the second area couldn't seem to be scrolled without jumping back to the top. What is needed is a way of doing one thing for one area and the reverse for the other, not the same thing for both of them. If you examine my code you will see a test for which area is initiating the movement. In mburt's model, he has two separate events for each area. This is the most rudimentary (and often the best) way of ensuring that one item does one thing and the other the reverse.

I'm not really thrilled with any of the methods, including my own, as there is no support in Opera for it. I've looked around a bit to find some hooks Opera could use to accomplish this but, so far have come up empty. Which reminds me, my method should have a few object tests included to at least spare browsers like Opera from trying to execute code that they cannot.

shachi
08-20-2006, 11:48 AM
Yea opera, most of the time is an exception(for e.g the opacity problem and a lot others). I wonder why they made it like so.

jscheuer1
08-20-2006, 05:31 PM
Yea opera, most of the time is an exception(for e.g the opacity problem and a lot others). I wonder why they made it like so.

I think Opera started out with the premise that they didn't want to be like everybody else and didn't want to slow down the browsing experience with frills.

They have since added support for generic opacity which is what FF (although it still does support the proprietary -moz-opacity) and Safari now use.

Oftentimes with Opera, there is a way around, to make a script work but, script writers rarely take the time to find it. Usually, if the script works in Opera, they just add it to the list of browsers that their script works in, if not - they leave Opera off this list.

And, while I was looking around for the hooks that I mentioned in my last post, I came across an Opera beta tester's message board where there was quite a bit of mention of properly including (it's already a property but reports a textarea's position on the page not its scroll state) the scrollTop property for textarea so, it may not be too far off.

ItsMeOnly
08-20-2006, 06:09 PM
In related manner: I'd need to "autoscroll" a div with overflowing content to its "bottom edge", any idea how to comfortably add this to...


messages = new Array(
"sh: Command not found.",
"Bad command or filename.",
"Press any key...",
"You have reached a command which has been disconnected, or is no longer in service. If you reach.."
// [...]
);

function enterCommand () {
commandVal = document.getElementById('command').value;

if (commandVal != "") {
myNum = Math.floor(Math.random() * messages.length);
document.getElementById('command').value = "";
document.getElementById('consoletext').innerHTML += "<br />guest@bach:~/$ \n" + commandVal + "<br />\n" + messages[myNum];
}
}

?

jscheuer1
08-20-2006, 06:25 PM
Show me the whole page (a link to it or the code).

Basically you will need to get the innermost division that contains the actual content, measure its offsetHeight and set its top position it accordingly in relation to its container's height. This is facilitated by having it be an absolutely positioned div within a relatively positioned one. The relatively positioned one is the one with the overflowing content and scroll bars.

ItsMeOnly
08-20-2006, 06:37 PM
textObj = document.getElementById('consoletext');
textObj.scrollTop = textObj.scrollHeight;

works like a charm :)

http://rambo.id.uw.edu.pl - check out System Console :), have fun, and if you'd want to add something, fire away :)

jscheuer1
08-20-2006, 07:34 PM
textObj = document.getElementById('consoletext');
textObj.scrollTop = textObj.scrollHeight;

works like a charm :)

http://rambo.id.uw.edu.pl - check out System Console :), have fun, and if you'd want to add something, fire away :)

I'll have a closer look when I have more time but, appears to do nothing in IE or Opera.

ItsMeOnly
08-23-2006, 11:43 AM
I'll have a closer look when I have more time but, appears to do nothing in IE or Opera.
dang, you were right, not only in IE's and Opera's pressing enter doesn't trigger onchange event, but also max-height doesn't fire up on IE, any thoughts?

jscheuer1
08-23-2006, 02:53 PM
Well, since you are already using javascript, you could easily use a style expression - a proprietary IE feature - for max-height in that browser which, you guessed it, doesn't support max or min dimensions as style properties.

The way that works is (in an ordinary stylesheet):


selector {
height:expression(Math.min(this.offsetHeight, 300)+'px');
}

In the above example, 300 would be the max-height in pixels. You may use any valid javascript in these expressions, including references to the return value of functions. Other browsers will ignore this, seeing it simply as an invalid style declaration.

The onkeypress event could be used instead of onchange but, you would have to test for the character code of the key used to only execute for the enter key. See:

http://jennifermadden.com/javascript/stringEnterKeyDetector.html

This should work cross browser.

ItsMeOnly
08-23-2006, 05:40 PM
The onkeypress event could be used instead of onchange but, you would have to test for the character code of the key used to only execute for the enter key. See:

http://jennifermadden.com/javascript/stringEnterKeyDetector.html

This should work cross browser.
That resource is gold for me, thanks: this was I can make input invisible, and cover entire "Console" area, while the demonstrated script can append characters in div underneath, thus, now I can enable scrolling :)

And there it goes (the usual link- above), implementing left scrollbar was piece of cake (direction: rtl followed by direction: ltr in child div)

mburt
01-31-2007, 05:10 PM
textObj = document.getElementById('consoletext');
textObj.scrollTop = textObj.scrollHeight;
Don't forget to use the var keyword.

var textObj = document.getElementById('consoletext');
textObj.scrollTop = textObj.scrollHeight;