CSS Textarea在您键入文本时展开

时间:2011-02-10 06:57:05

标签: javascript jquery html css textarea

我有一个Textarea用户可以输入文字。默认情况下,它的高度为17px。但是,如果用户插入大量文本,我希望文本区域相应地扩展。有没有办法用CSS做到这一点?在此先感谢!!

18 个答案:

答案 0 :(得分:24)

单独使用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

它重量轻,易于使用。这是它的完成方式。定义textarea id。在</body>之前包含jquery js文件。然后在脚本标记之间发出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>

答案 1 :(得分:20)

这个jQuery插件非常棒: http://www.jacklmoore.com/autosize

我测试了很多这些,这是迄今为止最好的。还给出了一个使用非常光滑的CSS过渡效果的示例。

答案 2 :(得分:16)

**请注意,这与上面的Woody的答案非常相似,但是想稍微扩展它并提供一个运行代码示例,现在Stack允许我们嵌入它们。

阅读了所有这些内容并尝试了几个插件后,我发现这一切都没有像我希望的那样完成。我做了以下操作 - 当你在扩展之前滚动时,在场的顶部有轻微的抖动,但它适用于我。我使用了jquery,但是可以通过抓取填充值而不是使用内部高度来轻松完成javascript:

  • 在CSS
  • 中的 textarea 上设置最小高度
  • 将溢出设置为隐藏以进行垂直滚动(我只是想垂直展开)
  • 如果滚动高度高于height + padding(innerHeight),则将高度设置为每个 keyup 事件的滚动高度减去填充。
  • 如果滚动高度不高,我将高度重新设置为1,然后将高度设置为滚动高度减去填充(缩小高度)。如果您最初没有重置为较小的高度,则滚动高度不会缩小。

&#13;
&#13;
$(function() {
  $('#myTextArea').on('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);
    }
  });
});
&#13;
#myTextArea {
  width: 250px;
  min-height: 35px;
  overflow-y: hidden;
}
&#13;
<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>
&#13;
&#13;
&#13;

答案 3 :(得分:12)

您不需要插件。这适用于任何大小,高度或行大小的textareas,仅在内容超出textarea时才有效。首先将目标textareas上的溢出设置为隐藏并调整为无,然后将以下功能添加到要自动增长的textareas中。它不仅会在用户输入时增加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不应该增长。

谨慎的做法是添加一个No JS选项,为那些没有Javascript的人重新启用溢出和调整大小,否则他们将被困在一个小盒子里。

答案 4 :(得分:12)

我知道这有点晚了,但我不得不说有一种方法可以使用<div> contenteditable属性来模拟所需的行为。

&#13;
&#13;
.textareaElement {
  width: 300px;
  min-height: 17px;
  border: 1px solid #ccc;
  max-height: 150px;
  overflow-x: hidden;
  overflow-y: auto;
}
&#13;
<div class="textareaElement" contenteditable></div>
&#13;
&#13;
&#13;

只需设置你的最小和最大高度,使用适当的溢出值,你就可以获得功能齐全的纯CSS扩展文本框,这也得到了很好的支持。

enter image description here

答案 5 :(得分:4)

使用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>

答案 6 :(得分:1)

我一直在寻找纯粹的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);

答案 7 :(得分:1)

有点晚了,但这对我来说就像一种魅力,它在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>

答案 8 :(得分:1)

老问题,但你可以这样做:

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);
        }
    });

这样,自动调整大小将应用于具有“text-area”类的任何textarea。删除文本时也会收缩。

的jsfiddle:

https://jsfiddle.net/rotaercz/46rhcqyn/

答案 9 :(得分:1)

这似乎更有效率并处理max-height

$(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)
        }
});

答案 10 :(得分:1)

我使用以下内容(当然使用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');
});

请注意,它会响应各种事件,只会增加行数(即不会减少),触发初始更改(例如,在浏览到包含大量行的表单时调整大小)

答案 11 :(得分:1)

在您键入时扩展textarea

在textarea中输入内容以查看效果

<script>    
function increseRows(selector)
{
    $(selector).attr("rows", $(selector).val().split("\n").length+1||2);
}
</script>

expanding textarea as you type

答案 12 :(得分:0)

使用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会出现并消失,因此您可以测量其高度。你永远不会在浏览器中看到它。

希望这适合你!

P.S。我使用React,所以我不得不改变我的解决方案,使其与框架无关。所以它可能有错误或语法错误。例如。您可能需要查询文档才能找到种植者div。

答案 13 :(得分:0)

如果您使用的是Angular2 / 4,那么可以使用一个很棒的directive here

有关何时将数据动态加载到textarea以获取解决方法,请参阅问题列表。除了该问题,它可以与ReactiveForms和Template表单一起使用。

作为参考,这是指令代码:

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';
  }

}

答案 14 :(得分:0)

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';

};

为我工作

-XX:CMSTriggerRatio

答案 15 :(得分:0)

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>

答案 16 :(得分:0)

提出了针对React Angular或Vue的简单解决方案。

您只需要将textarea包裹在div中,将textarea的内容写在div中,并给出textarea的绝对位置,高度和宽度100%(不要忘记在div上的相对位置)。

因此,现在divtextarea完全重叠,并且当div由于里面的文本而展开时,textarea将自动这样做。

别忘了设置完全相同的填充,字体大小和字体系列。

答案 17 :(得分:0)

这对我有用

$(".textarea").on("keyup input", function(){
    $(this).css('height', 'auto').css('height', this.scrollHeight+(this.offsetHeight - 
    this.clientHeight));
 });