I am using the accepted answer to this question to build a textarea that expands vertically as text overflows:
you should scroll the page to: scroll bar position + (textarea height after resize - textarea height before resize)
here is the code:
function resize () {
var scrollLeft = window.pageXOffset ||
(document.documentElement || document.body.parentNode || document.body).scrollLeft;
var scrollTop = window.pageYOffset ||
(document.documentElement || document.body.parentNode || document.body).scrollTop;
var prevHeight = text.style.height.slice(0, -2);
text.style.height = "auto";
var nextHeight = text.scrollHeight;
text.style.height = text.scrollHeight + 'px';
window.scrollTo(scrollLeft, scrollTop + (nextHeight - prevHeight));
}
OR you can do this using jquery (based on this answer):
$('body').on('keyup', 'textarea', function (e) {
var scrollTop = $(document).scrollTop();
var prevHeight = $(this).height();
$(this).css('height', 'auto');
var nextHeight = this.scrollHeight;
$(this).height(nextHeight);
$(document).scrollTop(scrollTop + (nextHeight - prevHeight));
});
$( 'textarea' ).keyup();
A way to do the accepted answer when the textarea is in a scrollable div:
function getScrollParent(node) {
if (node == null) {
return null;
}
if (node.scrollHeight > node.clientHeight) {
return node;
} else {
return getScrollParent(node.parentNode);
}
}
function resize(){
// 'this' is the textarea
const scrollParent = getScrollParent(this);
const scrollTop = scrollParent ? scrollParent.scrollTop : null;
const scrollLeft = scrollParent ? scrollParent.scrollLeft : null;
this.style.height = "auto";
this.style.height = this.scrollHeight + "px";
if (scrollParent) {
scrollParent.scrollTo(scrollLeft, scrollTop);
}
};
Save the scrollLeft
, scrollTop
values, and then restore them after resizing the textarea:
function resize () {
var scrollLeft = window.pageXOffset ||
(document.documentElement || document.body.parentNode || document.body).scrollLeft;
var scrollTop = window.pageYOffset ||
(document.documentElement || document.body.parentNode || document.body).scrollTop;
text.style.height = "auto";
text.style.height = text.scrollHeight + 'px';
window.scrollTo(scrollLeft, scrollTop);
}
JSFiddle: http://jsfiddle.net/losnir/nnkeH/1
My response is based on the fiddle in the accepted answer for: height of textarea increases when value increased but does not reduce when value is decreased.
This works on page load and when the text is altered in any way (cut, paste, typing, etc.)
$('textarea').on('keyup keydown', function () {
var $this = $(this);
var initialHeight = $this.height();
$this
.height(initialHeight - 40)
.height($this[0].scrollHeight + 20);}).trigger('keyup');
The reason I grab the initial height is so that the textarea doesn't have to jump to 1 or any other static number to trigger a value for scrollHeight. (it's my understanding that is what causes the screen to change scrolling because the textbox is set to that static height (usually 1) and then expands) The reason that I add 20 to scrollHeight is because sometimes scrollHeight is off by 1 or 2px and the text looks bunched up at the bottom. So to give it more space I personally add 20.