使用jQuery自动扩展文本框大小

135

如何使用jQuery实现自动扩展文本域?

我有一个文本框,用于解释会议议程,因此当我的议程文本不断增加时,我希望扩展该文本框的区域。


我认为文本区域是自动可扩展的。 - andrew Sullivan
2
可能是搜索最终调整大小的文本区域的重复问题。 - rjmunro
请考虑修改您的问题并删除“jQuery”一词。 - vsync
32个回答

171

如果您不想使用插件,有一个非常简单的解决方案。

$("textarea").keyup(function(e) {
    while($(this).outerHeight() < this.scrollHeight + parseFloat($(this).css("borderTopWidth")) + parseFloat($(this).css("borderBottomWidth"))) {
        $(this).height($(this).height()+1);
    };
});

你可以在这个jsFiddle中看到它的工作原理,我在那里回答了另一个关于文本框的问题。

如果你想要将其反转或者缩小,可以参考这个jsFiddle

如果你确实需要一个插件

@Jason 设计了一个插件,可以在这里找到。


1
我不得不删除 + parseFloat($(this).css("borderTopWidth"))+ parseFloat($(this).css("borderBottomWidth")),否则它会无限循环,而且这与使用 Bootstrap 样式的文本区域有关。 - blacelle
3
无jQuery版本: if (this.clientHeight < this.scrollHeight) { this.style.height = this.scrollHeight + 'px'; }(注:该代码用于自动扩展文本框的高度以适应其内容,如果文本内容超过了文本框的高度,则将文本框的高度设置为文本内容的高度。) - Georgii Ivankin
3
@metakungfu,与其只是进行下投票,不如帮助改进这个答案。目前我没有任何测试苹果设备和Safari浏览器的方法,因为Safari for Windows早已停止更新。所以我无法确定原因是什么导致它无法运行。从代码角度来看,这个解决方案没有任何问题。你确定是代码出了错,而不是在jsfiddle中Safari浏览器出了问题吗? Safari浏览器非常挑剔,并且Fiddle最近经历了一次大规模更新。也许您可以打开开发人员工具并提供更多详细信息? - SpYk3HH
1
还需要将文本区域的overflow-y属性设置为hidden以防止闪烁滚动。 - iulial
2
如果我想删除添加的行,文本框的扩大尺寸仍然保持不变,是否可能它也可以自动调整回来? - Steven
显示剩余2条评论

117

我尝试过很多,而这个插件非常好用。 链接失效。新版本在这里。请看下面旧版的内容。
你可以在文本区域中按住Enter键来尝试。将此效果与其他自动扩展文本框插件进行比较...

编辑,基于评论

$(function() {
   $('#txtMeetingAgenda').autogrow();
});

注意:您应该包含所需的js文件...

为了防止文本区域中的滚动条在扩展/收缩期间闪烁,您还可以将overflow设置为hidden

$('#textMeetingAgenda').css('overflow', 'hidden').autogrow()




更新:

上面的链接已经失效了。但是你仍然可以在这里获取JavaScript文件。


如果我的文本框ID是txtMeetingAgenda,那么我如何在jQuery中实现自动文本区域属性? - Piyush
这里是否定义了点击事件? - Piyush
这段内容与文本区域有关,但是文本框呢?这个插件也适用于文本框吗? - Piyush
1
这个插件不太好用,试试autosize,它更好。 - julesbou
1
当文本区域增长时,它可以正常工作。但是当您开始删除文本时,它不会自动减小高度。 - ekashking

33

使文本区域变大/变小。此演示利用jQuery进行事件绑定,但这并不是必须的。
不支持IE - IE不响应rows属性更改

演示页面


HTML

<textarea class='autoExpand' rows='3' data-min-rows='3' placeholder='Auto-Expanding Textarea'></textarea>

CSS

textarea{  
  display:block;
  box-sizing: padding-box;
  overflow:hidden;

  padding:10px;
  width:250px;
  font-size:14px;
  margin:50px auto;
  border-radius:8px;
  border:6px solid #556677;
}

Javascript(更新版)

$(document)
    .one('focus.textarea', '.autoExpand', function(){
        var savedValue = this.value;
        this.value = '';
        this.baseScrollHeight = this.scrollHeight;
        this.value = savedValue;
    })
    .on('input.textarea', '.autoExpand', function(){
        var minRows = this.getAttribute('data-min-rows')|0,
            rows;
        this.rows = minRows;
        rows = Math.ceil((this.scrollHeight - this.baseScrollHeight) / 16);
        this.rows = minRows + rows;
    });

2
因为代码必须等待一段时间,以便您键入的字母被打印在文本区域内,并因此更改文本区域的尺寸。 - vsync
1
我明白了,当文本从任何来源复制(CTRL+V)时,解决方案会出现问题。但是,如果手动输入文本,则非常棒且非常流畅。 - Satya Kalluri
1
@vsync:如果要修改以适用于多个文本区域,该怎么做呢?例如,您有textarea1和textarea2,并且希望两者都可以自动增长。 - jmoreno
1
这应该是最佳答案!如果有人感兴趣,我基于此发布了一个问题:https://dev59.com/Porda4cB1Zd3GeqPJ0Ll - gsamaras
1
@AllyMurray - 我现在已经更新到16,因为它似乎能够提供更好的结果。是的,那就是预期的行高。 - vsync
显示剩余14条评论

27
您可以尝试这个。

$('#content').on('change keyup keydown paste cut', 'textarea', function () {
        $(this).height(0).height(this.scrollHeight);
    }).find('textarea').trigger("change");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="content">
  <textarea>How about it</textarea><br />
  <textarea rows="5">111111
222222
333333
444444
555555
666666</textarea>
</div>


1
如果你想从$(this)获取scrollHeight,你可以使用$(this).prop('scrollHeight');代替 ;) - Samuel Vicent
4
它在每一个换行处闪烁。 - joe

21

3
自适应大小插件是最好的。 - Yarin

11

多亏了SpYk3HH,我从他的解决方案开始,并将其转化为这个解决方案,它增加了收缩功能,而且更简单更快速,我想。

$("textarea").keyup(function(e) {
    $(this).height(30);
    $(this).height(this.scrollHeight + parseFloat($(this).css("borderTopWidth")) + parseFloat($(this).css("borderBottomWidth")));
});

已在当前Chrome、Firefox和Android 2.3.3浏览器中进行测试。

某些浏览器中可能会看到滚动条闪烁。添加此CSS以解决该问题。

textarea{ overflow:hidden; }

它根本不起作用:/ 每输入一个字符,它都会增加高度。 - vsync
1
它对我来说完美地运作!简单的代码中绝对没有你所说的那样的问题。 - drolex
1
是的,我现在看到了,你的代码必须有一行最初将高度设置为30的代码。这可能是一行不必要的代码,因为它强制开发人员调整代码,而不是让代码理解并适应文本区域。 - vsync
1
那是不正确的。开发人员不需要调整代码。将高度设置为30是必需的,并且适用于所有情况。用户永远看不到这种情况发生。这就是它能够缩小文本区域的方式。代码确实理解并适应文本区域。这就是整个重点所在。 - drolex
你是正确的。演示页面:http://jsbin.com/ObEcoza/2/edit(将高度设置为“1px”似乎更好) - vsync
显示剩余2条评论

10

为了定义一个自动可扩展的文本框,您需要执行两个步骤:

  1. 在文本框内按Enter键输入多行内容后将其扩展。
  2. 在失去焦点时缩小它,以获取用户输入的实际大小(额外的功能)。

这里是一个手写函数来完成此任务。

几乎所有浏览器都可以正常工作(低于IE7)。 这是方法:

    //Here is an event to get TextArea expand when you press Enter Key in it.
    // intiate a keypress event
    $('textarea').keypress(function (e) {  
       if(e.which == 13)   {   
       var control = e.target;                     
       var controlHeight = $(control).height();          
      //add some height to existing height of control, I chose 17 as my line-height was 17 for the control    
    $(control).height(controlHeight+17);  
    }
    }); 

$('textarea').blur(function (e) {         
    var textLines = $(this).val().trim().split(/\r*\n/).length;      
    $(this).val($(this).val().trim()).height(textLines*17);
    });

这里是一篇关于此事的帖子。


6

1
一个文本框(我猜是输入文本元素)不是多行的。使用文本区域,但适当地设置样式 - 行数、列数等,然后像上面那样使用自动增长插件。 - richsage

4
每个人都应该尝试这个jQuery插件:xautoresize-jquery。它非常好用,应该可以解决你的问题。

这个给了我最好的结果,而且也很容易实现。 - psic4t

4
function autosize(textarea) {
    $(textarea).height(1); // temporarily shrink textarea so that scrollHeight returns content height when content does not fill textarea
    $(textarea).height($(textarea).prop("scrollHeight"));
}

$(document).ready(function () {
    $(document).on("input", "textarea", function() {
        autosize(this);
    });
    $("textarea").each(function () {
        autosize(this);
    });
});

(因为它使用了input事件,所以它不能在Internet Explorer 9或更早版本中工作)


在我的项目中,由于我是通过 Jquery 和 typescript 渲染整个页面,你的解决方案是我能够解决问题的唯一途径,谢谢。 - Harry Sarshogh

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