【发布时间】:2011-06-24 15:58:13
【问题描述】:
我有一个文本区域,用户可以在其中输入文本。默认情况下,它的高度为 17px。但是,如果用户插入大量文本,我希望文本区域相应扩展。有没有办法用 CSS 做到这一点?提前致谢!!
【问题讨论】:
-
没有人想出一个无 jquery 的解决方案来解决这个问题吗? :-(
标签: javascript jquery html css textarea
我有一个文本区域,用户可以在其中输入文本。默认情况下,它的高度为 17px。但是,如果用户插入大量文本,我希望文本区域相应扩展。有没有办法用 CSS 做到这一点?提前致谢!!
【问题讨论】:
标签: javascript jquery html css textarea
仅靠 CSS 无法做到这一点。试试 autogrow jquery 插件。 https://github.com/jaz303/jquery-grab-bag/blob/master/javascripts/jquery.autogrow-textarea.js
您还可以在此处查看自动增长演示 http://onehackoranother.com/projects/jquery/jquery-grab-bag/autogrow-textarea.html
它轻巧且易于使用。这是它是如何完成的。定义您的文本区域 ID。在</body> 之前包含jquery js 文件。然后在script标签之间,发出jquery命令$("#txtInput").autoGrow();
<body>
<textarea id="txtInput"></textarea>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js" type="text/javascript"></script>
<script>
$("#txtInput").autogrow();
</script>
</body>
【讨论】:
$('#textInput').autoGrow(); 应该是$(#txtInput).autogrow();
我知道这有点晚了,但我不得不说有一种方法可以使用 <div> 和 contenteditable 属性来模拟所需的行为。
.textareaElement {
width: 300px;
min-height: 17px;
border: 1px solid #ccc;
max-height: 150px;
overflow-x: hidden;
overflow-y: auto;
}
<div class="textareaElement" contenteditable></div>
只需设置您的最小和最大高度,使用适当的溢出值,您就拥有功能齐全的纯 CSS 扩展文本框,这也得到了很好的支持。
【讨论】:
<div> 块中。所以innerHTML变成了一个文本节点,后面跟着一堆<div>s。
这个 jQuery 插件非常棒: http://www.jacklmoore.com/autosize
我已经测试了一堆,这是迄今为止最好的。还给出了一个使用 CSS 过渡效果的例子,非常漂亮。
【讨论】:
**请注意,这与上面 Woody 的回答非常相似,但想对其进行一些扩展并提供一个运行代码示例,因为 Stack 允许我们嵌入它们。
在阅读了所有这些并尝试了几个插件之后,我发现这些都没有像我希望的那样工作。我使用 jquery 完成了以下操作,但可以通过抓取填充值而不是使用内部高度来轻松地使用 javascript 完成:
$(function() {
$('#myTextArea').on('input keyup paste', function() {
var $el = $(this),
offset = $el.innerHeight() - $el.height();
if ($el.innerHeight() < this.scrollHeight) {
// Grow the field if scroll height is smaller
$el.height(this.scrollHeight - offset);
} else {
// Shrink the field and then re-set it to the scroll height in case it needs to shrink
$el.height(1);
$el.height(this.scrollHeight - offset);
}
});
});
#myTextArea {
width: 250px;
min-height: 35px;
overflow-y: hidden;
}
<script src="https://code.jquery.com/jquery-2.2.3.min.js"></script>
<textarea id="myTextArea" placeholder="Hit enter a few times, it should expand"></textarea>
【讨论】:
您不需要插件。这适用于任何大小、高度或行大小的 textarea,并且仅在内容超出 textarea 时才有效。首先将目标文本区域上的溢出设置为隐藏并将大小调整为无,然后将以下功能添加到要自动增长的文本区域中。它不仅会在用户键入时增加文本区域的大小,而且还会在用户删除内容时自动缩小。
$('textarea').on('paste input', function () {
if ($(this).outerHeight() > this.scrollHeight){
$(this).height(1)
}
while ($(this).outerHeight() < this.scrollHeight + parseFloat($(this).css("borderTopWidth")) + parseFloat($(this).css("borderBottomWidth"))){
$(this).height($(this).height() + 1)
}
});
它通过测量 textarea 的滚动高度是否大于外部高度来工作,只有当文本超过 textarea 可以容纳的文本时才会出现这种情况 - 并且它会考虑边框大小以提高准确性。使用粘贴和输入意味着它只会在用户物理更改文本区域的值时增加,而不是在他们按下任何键时。它很小,但是当有人按下箭头键或其他东西时,文本区域不应该增长。
为那些没有 Javascript 的人添加一个 No JS 选项来重新启用溢出和调整大小可能是明智的,否则他们会被一个小盒子卡住。
【讨论】:
为此使用 JavaScript。
此脚本在每次击键后检查文本区域的长度(来自here 的copypasta):
<textarea name="x" onKeyUp="SetNewSize(this);" cols="5" rows="4"></textarea>
<script language="javascript">
function SetNewSize(textarea){
if (textarea.value.length > 5){
textarea.cols = 50;
textarea.rows = 50;
} else{
textarea.cols = 10;
textarea.rows = 15;
}
}
</script>
【讨论】:
有点晚了,但这对我来说就像一个魅力,它在 jquery 中:
此文本区域的限制高度为 200 像素,起始高度为 22 像素。填充有助于将文本保持在一个好的位置,但是,我们必须根据字体的大小来调整权重。
在另一个问题中也有类似的答案,但这个更完整一些。
$('textarea').each(function () {
// Do something if you want
}).on('input', function () {
this.style.height = 'auto';
// Customize if you want
this.style.height = (this.scrollHeight - 30) + 'px'; //The weight is 30
});
textarea{
padding: 7px;
width: 50%;
height: 22px;
max-height: 200px;
resize: none;
overflow-y: scroll;
font-size: 16px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>Textarea:</div>
<textarea></textarea>
【讨论】:
在您键入时扩展文本区域
在 textarea 中输入内容以查看效果
<script>
function increseRows(selector)
{
$(selector).attr("rows", $(selector).val().split("\n").length+1||2);
}
</script>
【讨论】:
||是什么意思
false,则它被用于默认为 2 行。
我使用以下(当然是 jQuery):
$(function () {
'use strict';
$("textarea").on('change keyup paste input', function () {
$(this).attr("rows", Math.max($(this).val().split("\n").length || 1, $(this).attr("rows") || 1));
$(this).css("width", $(this).css("width"));
}).trigger('change');
});
请注意,它响应各种事件,仅增加行数(即不减少),触发初始更改(例如,在浏览回具有大量行的表单时调整大小)
【讨论】:
这似乎更有效率并且可以处理最大高度
$(ctrl).on('paste input', function () {
var dyLineHeight, dyMax, dyHeight;
if ($(this).outerHeight() > this.scrollHeight)
$(this).height($(this).outerHeight() - parseFloat($(this).css("borderBottomWidth")) - parseFloat($(this).css("borderTopWidth")));
dyLineHeight = Math.max(3, parseInt($(this).css("line-height")));
dyMax = parseInt($(this).css("max-height"));
while ($(this).outerHeight() < this.scrollHeight + parseFloat($(this).css("borderTopWidth")) + parseFloat($(this).css("borderBottomWidth")))
{
dyHeight = $(this).height();
if (dyHeight >= dyMax)
break;
$(this).height(dyHeight + dyLineHeight)
}
});
【讨论】:
我一直在寻找纯 js 解决方案(项目中没有 jquery)并最终编写自己的解决方案。它非常快,没有兼容性问题,并且不需要额外的库。
需要注意的一个细节是你需要在新字符出现之前放大框,但在字符消失后缩小框(按退格键或删除后)
function updateSize(e) {
let text = e.target.value + String.fromCharCode(event.keyCode);
e.target.rows = text.split(/\r\n|\r|\n/).length;
}
function keyDownUpdateSize(e) {
if (event.keyCode != 8 && event.keyCode != 46)
updateSize(e);
}
function keyUpUpdateSize(e) {
if (event.keyCode == 8 || event.keyCode == 46)
updateSize(e);
}
document.querySelector(selector_to_your_textarea).addEventListener("keydown", keyDownUpdateSize);
document.querySelector(selector_to_your_textarea).addEventListener("keyup", keyUpUpdateSize);
【讨论】:
老问题,但你可以这样做:
html:
<textarea class="text-area" rows="1"></textarea>
jquery:
var baseH; // base scroll height
$('body')
.one('focus.textarea', '.text-area', function(e) {
baseH = this.scrollHeight;
})
.on('input.textarea', '.text-area', function(e) {
if(baseH < this.scrollHeight) {
$(this).height(0).height(this.scrollHeight);
}
else {
$(this).height(0).height(baseH);
}
});
这样,自动调整大小将应用于任何具有“文本区域”类的文本区域。删除文本时也会缩小。
jsfiddle:
【讨论】:
使用 Javascript。 textarea 的行为类似于 textarea,并且您想要更改它(您希望它的行为类似于 div),因此您必须修改您想要的行为。
这是我几个月前在某个地方找到的解决方案,但无法再次找到。它可能添加了我自己的味道:
标记:
<div>
<textarea class='my-textarea' />
<div className='my-textarea autogrow' style="display: 'none';" />
</div>
样式:
.my-textarea {
border: 1px solid #bbb;
font-family: Helvetica;
font-size: 15px;
overflow: hidden;
padding: 5px;
resize: none;
}
// Needs same styles as the textarea except overflow.
.autogrow {
overflow: auto !important;
}
将此事件侦听器获取到 textarea 的 change 事件:
function growTextarea(e) {
const { value } = e.target
const textarea = e.target
const { grower } = this
grower.style.display = 'block'
grower.innerHTML = value.length ? value : 'x'
textarea.style.height = grower.offsetHeight + 'px'
grower.style.display = 'none'
}
它是如何工作的?基本上,div 的扩展是您希望 textarea 的扩展表现的样子。因此,您正在制作一个与 textarea 样式相同的 div,并将 textarea 的值放入 div 中。然后获取 div 的高度并将 textarea 的高度设置为该高度。
使用 display none 和 block,div 出现和消失,因此您可以测量它的高度。你永远不会在浏览器中真正看到它。
希望这对你有用!
附:我使用 React,所以我不得不将我的解决方案更改为与框架无关。所以它可能有错误或语法错误。例如。您可能需要查询文档才能找到种植者 div。
【讨论】:
如果您使用的是 Angular2/4,那么有一个很棒的 directive here 可以工作。
当您将数据动态加载到文本区域时,请参阅问题列表以获取解决方法。除了这个问题,它适用于 ReactiveForms 和模板表单。
作为参考,这是指令代码:
import { Input, AfterViewInit, ElementRef, HostListener, Directive} from '@angular/core';
@Directive({
selector: 'textarea[autosize]'
})
export class Autosize implements AfterViewInit {
private el: HTMLElement;
private _minHeight: string;
private _maxHeight: string;
private _lastHeight: number;
private _clientWidth: number;
@Input('minHeight')
get minHeight() {
return this._minHeight;
}
set minHeight(val: string) {
this._minHeight = val;
this.updateMinHeight();
}
@Input('maxHeight')
get maxHeight() {
return this._maxHeight;
}
set maxHeight(val: string) {
this._maxHeight = val;
this.updateMaxHeight();
}
@HostListener('window:resize', ['$event.target'])
onResize(textArea: HTMLTextAreaElement) {
//Only apply adjustment if element width had changed.
if (this.el.clientWidth === this._clientWidth) return;
this._clientWidth = this.element.nativeElement.clientWidth;
this.adjust();
}
@HostListener('input',['$event.target'])
onInput(textArea: HTMLTextAreaElement): void {
this.adjust();
}
constructor(public element: ElementRef){
this.el = element.nativeElement;
this._clientWidth = this.el.clientWidth;
}
ngAfterViewInit(): void{
// set element resize allowed manually by user
const style = window.getComputedStyle(this.el, null);
if (style.resize === 'both') {
this.el.style.resize = 'horizontal';
}
else if (style.resize === 'vertical') {
this.el.style.resize = 'none';
}
// run first adjust
this.adjust();
}
adjust(): void{
// perform height adjustments after input changes, if height is different
if (this.el.style.height == this.element.nativeElement.scrollHeight + "px") return;
this.el.style.overflowX = 'hidden';
this.el.style.height = 'auto';
this.el.style.height = this.el.scrollHeight + "px";
}
updateMinHeight(): void{
// Set textarea min height if input defined
this.el.style.minHeight = this._minHeight + 'px';
}
updateMaxHeight(): void{
// Set textarea max height if input defined
this.el.style.maxHeight = this._maxHeight + 'px';
}
}
【讨论】:
function autoExpand(field) {
// Reset field height
field.style.height = 'inherit';
// Get the computed styles for the element
var computed = window.getComputedStyle(field);
// Calculate the height
var height = parseInt(computed.getPropertyValue('border-top-width'), 10)
+ parseInt(computed.getPropertyValue('padding-top'), 10)
+ field.scrollHeight
+ parseInt(computed.getPropertyValue('padding-bottom'), 10)
+ parseInt(computed.getPropertyValue('border-bottom-width'), 10);
field.style.height = height + 'px';
};
为我工作
https://gomakethings.com/automatically-expand-a-textarea-as-the-user-types-using-vanilla-javascript/
【讨论】:
var textarea = document.querySelector('textarea');
textarea.addEventListener('keydown', autosize);
function autosize(){
var el = this;
setTimeout(function(){
el.style.cssText = 'height:auto; padding:0';
el.style.cssText = 'height:' + el.scrollHeight + 'px';
},0);
}
textarea{
overflow:hidden;
padding:10px;
width:250px;
font-size:14px;
margin:50px auto;
display:block;
border-radius:10px;
border:6px solid #556677;
}
<textarea rows="6" >
CSS Textarea that expands as you type text
rows Specifies the visible number of lines in a text area and cols Specifies the visible width of a text area
</textarea>
【讨论】:
这对我有用
$(".textarea").on("keyup input", function(){
$(this).css('height', 'auto').css('height', this.scrollHeight+(this.offsetHeight -
this.clientHeight));
});
【讨论】:
为 React Angular 或 Vue 提出了简单的解决方案。
您只需要将textarea 包裹在div 中,将textarea 的内容写入div 并给textarea 绝对位置、高度和宽度100%(不要忘记相对在div 上的位置)。
所以现在div 和textarea 完美叠加,当div 因为里面的文字而扩展时,textarea 会自动这样做。
不要忘记设置完全相同的填充、字体大小和字体系列。
【讨论】: