EN
JavaScript - how to make textarea autogrow?
6
points
In this short article, we are going to look at how to make textarea
element autogrowing according to contained text using JavaScript.
1. Scroll height detection
Approach presented in this ection uses following fact: when height
is set as auto
we are able to get scrollHeight
equal to content height that can be used to set as current textarea
height
.
Practical example:
// ONLINE-RUNNER:browser;
<!doctype html>
<html>
<body>
<textarea style="resize: none" id="my-element">Type multi-line text here</textarea>
<script>
function preapreAutogrowing(element) {
var style = element.style;
function onAction() {
style.height = 'auto';
style.height = element.scrollHeight + 'px'; // element.scrollHeight should be accessed only when height is set to auto
}
element.addEventListener('input', onAction);
element.addEventListener('change', onAction);
var destroyed = false;
return {
update: onAction,
destroy: function() {
if (destroyed) {
return;
}
destroyed = true;
element.removeEventListener('input', onAction);
element.removeEventListener('change', onAction);
}
};
}
// Usage example:
var element = document.querySelector('#my-element');
var autogrowing = preapreAutogrowing(element);
element.value = '1\n2\n3\n4\n5\n6';
autogrowing.update(); // forces textarea size update according to contained text
// autogrowing.destroy();
</script>
</body>
</html>
2. Number of lines detection
This approach does not work if word wrapping is enabled.
Note: in different browsers effect can be different (Firefox and Chrome interpret number of rows different way when horisontal scroll is visible)
// ONLINE-RUNNER:browser;
<!doctype html>
<html>
<head>
<style>
textarea {
overflow-y: hidden;
white-space: pre;
resize: none;
}
</style>
<script>
function preapreAutogrowing(element) {
var expression = /\n/g;
function onAction() {
var text = element.value;
if (text) {
var match = text.match(expression);
if (match) {
element.rows = match.length + 2;
return;
}
}
element.rows = 2;
}
element.addEventListener('input', onAction);
element.addEventListener('change', onAction);
var destroyed = false;
return {
update: onAction,
destroy: function() {
if (destroyed) {
return;
}
destroyed = true;
element.removeEventListener('input', onAction);
element.removeEventListener('change', onAction);
}
};
}
</script>
</head>
<body>
<textarea id="my-element">Type multi-line text here...</textarea>
<script>
var element = document.querySelector('#my-element');
var autogrowing = preapreAutogrowing(element);
element.value = '1\n2\n3\n4\n5\n6';
autogrowing.update(); // forces textarea size update according to contained text
// autogrowing.destroy();
</script>
</body>
</html>