HTML文本框自动调整大小

14

我想要一个文本区域,它的大小始终与其中的文本一样。因此页面可以滚动,但文本区域不会滚动。
这是我到目前为止所做的:

<!DOCTYPE html>
<html>
<head>
<style type="text/css">
html, body {height: 100%;}
textarea {
border: none;
width: 100%;
height: 100%;
-webkit-box-sizing: border-box;
line-height: 44px;
font-family:Helvetica;
font-size: 17pt;
-webkit-tap-highlight-color: rgba(0,0,0,0);
background-image:url('linedBack@2x.png');
outline: none;
resize: none;
}
textarea.vert { resize:vertical; }
</style></head><body>
<textarea id="InputTextArea" placeholder="placeholder"></textarea>
</body></html>

1
可能是创建一个自动调整大小的文本区域的重复问题。 - Ciro Santilli OurBigBook.com
1
如果你正在使用React,我已经为此创建了一个包:https://www.npmjs.com/package/react-fluid-textarea - Martin Dawson
6个回答

16

根据内容行数调整TextArea大小。这是一个演示

JS(JavaScript)

function resizeTextarea (id) {
  var a = document.getElementById(id);
  a.style.height = 'auto';
  a.style.height = a.scrollHeight+'px';
}

function init() {
  var a = document.getElementsByTagName('textarea');
  for(var i=0,inb=a.length;i<inb;i++) {
     if(a[i].getAttribute('data-resizable')=='true')
      resizeTextarea(a[i].id);
  }
}

addEventListener('DOMContentLoaded', init);

HTML

<textarea id="InputTextArea" placeholder="placeholder" onkeyup="resizeTextarea('InputTextArea')"></textarea>

这个答案很简洁,但最终结果并不是非常顺畅。在输入区域扩展之前,文本会跳动得相当明显,导致用户体验不理想。Chris G.的答案提供了一个更好的解决方案。 - Zain Rizvi
"onkeydown"事件非常有效,可以立即调整文本区域的大小。谢谢。 - Ercan Akkök
1
@shubhra 为什么我们需要在 resizeTextarea 函数中添加 a.style.height = 'auto'; - Trần Hạnh

2

如果你正在使用AngularJS,你可以这样做:

<textarea ng-keyup="ctl.handleTextAreaHeight($event)"></textarea>

在您的控制器中使用以下代码:
this.handleTextAreaHeight = function (e) {
  var element = e.target;

  element.style.overflow = 'hidden';
  element.style.height = 0;
  element.style.height = element.scrollHeight + 'px';
};

这是我在到处搜索后找到的最佳答案。非常适用于纯JS,无需插件,无需jQuery。 - Vantalk

2

如果还有人需要,以下是我用纯js编写的代码。但首先,您可以查看这个: 使用jQuery自动扩展文本区域

最初的回答:

    var textAreas = document.getElementsByTagName('textarea');
    try {
        taLength = textAreas.length;
        for (i=0; i < taLength; i++) {
            var taId = textAreas[i].id;
            document.getElementById(taId).addEventListener('input', function(e) {
                e.target.style.height = "auto";
                    //This makes your textarea back to its original size. So you can replace it with any size you want it to have e.g. "120px"
                    //You may need some logic if you have multiple taxtareas with different original sizes
                e.target.style.height = e.target.scrollHeight+'px';
            });
        }
    }
    catch (err) {
        window.alert(err);
    }

我使用了shubhra的回答来构建这个。它很流畅,滚动条不会出现。翻译成中文为:“我使用了shubhra的回答来创建这个。它非常顺畅,且不会出现滚动条。”

2

如果有人需要Vue.js的解决方案,这里是一个Vue指令,用于自动调整文本区域大小。只需全局注册一次指令,即可在任何文本区域中使用。

Vue.directive('resizable', {
    inserted: function (el) {
        el.addEventListener('input', function(e) {
            e.target.style.height = "auto";
            e.target.style.height = e.target.scrollHeight + 'px';
        });
    }
});

HTML很容易,只需在文本框中添加v-resizable属性即可。

<textarea v-resizable></textarea>

特别感谢AniMir!我正在使用他的输入事件处理程序。


0
            <textarea
               id="newComm"
               class="form-control"
               name="comment"
               placeholder="Some text"
               cols="30"
               :rows="rowsHeight"
               wrap="soft"
               v-model.trim="newCommText"
               @input="changeRows"
               :style="'resize: none; overflow: hidden; line-height: '+lineHeight+'px;'"
        ></textarea>

    setup() {
    
    const newCommText = ref(null)
    const rowsHeightStart = ref(5)
    const rowsHeight = ref(rowsHeightStart.value)
    const lineHeight = ref(25)
    function changeRows (event) {
        rowsHeight.value = event.target.value.split("\n").length > rowsHeightStart.value ? event.target.value.split("\n").length : rowsHeightStart.value
    }

    return {
         rowsHeight, lineHeight, newCommText,
        changeRows
    }

0

仅设置height = scrollHeight时,如果设置了box-sizing:border-box,则无法达到目标。下面是一个解决方案,修复了这个问题,并允许文本区域再次缩小。

// auto resize the textareas
document.querySelectorAll("textarea").forEach(function (el) {
  el.addEventListener("input", function () {
    var cs = window.getComputedStyle(this);
    // reset height to allow textarea to shrink again
    this.style.height = "auto";
    // when "box-sizing: border-box" we need to add vertical border size to scrollHeight
    this.style.height = (this.scrollHeight + parseInt(cs.getPropertyValue("border-top-width")) + parseInt(cs.getPropertyValue("border-bottom-width"))) + "px";
  });
});

// compat window.getComputedStyle: IE9
// compat NodeList.forEach: No IE (but not necessary here)
* { box-sizing: border-box; }
textarea { width: 20%; }
#a { padding: 1em; }
#b { padding: 0; }
#c { max-height: 7em; }
#d {
  border-top: 10px solid blue;
  border-bottom: 10px solid blue;
}
<textarea id="a">1em padding</textarea>
<textarea id="b">0 padding</textarea>
<textarea id="c">max-height: 7em</textarea>
<textarea id="d">10px vertical borders</textarea>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接