使用 jQuery 自动展开文本区域

如何使用 jQuery 使文本区域自动展开?

我有一个文本框用于解释会议议程,所以当我的议程文本不断增长时,我想扩展这个文本框。

188389 次浏览

我以前使用过 织物区域扩展器 jQuery 插件,效果不错。

如果你不想要一个插件有一个非常简单的解决方案

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

看看它在 我曾经在这里回答过另一个文本区域的问题上的表现。

为了回答这样做的问题,反过来或使它更小,因为文本被删除: JsFiddle

如果你想要一个插件

@ Jason 在这里设计了一个

对于任何使用 Reigel 发布的插件的用户,请注意这会禁用 Internet Explorer 中的撤销功能(试试演示)。

如果这对你来说是一个问题,那么我建议使用 插件 @richage 代替,因为它不会受到这个问题的影响。有关更多信息,请参见 寻找最终调整大小的纹理区域上的第二个项目符号点。

我编写了这个 jquery 函数,它似乎可以工作。

但是,您需要在 css 中指定 min-height,并且除非您想要进行一些编码,否则它需要两位长。即12px;

$.fn.expand_ta = function() {


var val = $(this).val();
val = val.replace(/</g, "&lt;");
val = val.replace(/>/g, "&gt;");
val += "___";


var ta_class = $(this).attr("class");
var ta_width = $(this).width();


var min_height = $(this).css("min-height").substr(0, 2);
min_height = parseInt(min_height);


$("#pixel_height").remove();
$("body").append('<pre class="'+ta_class+'" id="pixel_height" style="position: absolute; white-space: pre-wrap; visibility: hidden; word-wrap: break-word; width: '+ta_width+'px; height: auto;"></pre>');
$("#pixel_height").html(val);


var height = $("#pixel_height").height();
if (val.substr(-6) == "<br />"){
height = height + min_height;
};
if (height >= min_height) $(this).css("height", height+"px");
else $(this).css("height", min_height+"px");
}

每个人都应该尝试这个 jQuery 插件: Xautoresize-jquery。它真的很好,应该解决你的问题。

我只是构建了这个函数来在页面加载上展开文本区域。只要将 each改为 keyup,当输入文本区时就会出现这种情况。

// On page-load, auto-expand textareas to be tall enough to contain initial content
$('textarea').each(function(){
var pad = parseInt($(this).css('padding-top'));
if ($.browser.mozilla)
$(this).height(1);
var contentHeight = this.scrollHeight;
if (!$.browser.mozilla)
contentHeight -= pad * 2;
if (contentHeight > $(this).height())
$(this).height(contentHeight);
});

在 Chrome,IE9和 Firefox 中测试。不幸的是,Firefox 有 这个窃听器,它返回的 scrollHeight值不正确,因此上面的代码包含了一个解决方案。

我修正了 Reigel 提供的答案(公认的答案)中的一些错误:

  1. HTML 实体的替换顺序现在不会在 shadow 元素中导致意外代码。(原来的“ >”改为“ & ampgt;”,在少数情况下会导致错误的身高计算)。
  2. 如果文本以换行结束,则阴影现在会获得一个额外的字符“ #”,而不是像原始文本那样具有固定的添加高度。
  3. 初始化后调整文本区域的大小确实会更新阴影的宽度。
  4. 添加单词包装: 为 shadow 使用 break-word,因此它与 texttarea 使用的是相同的换行方式(对于非常长的单词强制使用 break)

关于空间还有一些遗留问题。我没有看到双空格的解决方案,它们在 shadow (html 渲染)中显示为单个空格。不能通过使用 & nbsp; 解决此问题,因为空格应该中断。此外,文本区域在一个空格后面分割一条直线,如果没有空格,它将在前面的一点分割该直线。欢迎提出建议。

更正代码:

(function ($) {
$.fn.autogrow = function (options) {
var $this, minHeight, lineHeight, shadow, update;
this.filter('textarea').each(function () {
$this = $(this);
minHeight = $this.height();
lineHeight = $this.css('lineHeight');
$this.css('overflow','hidden');
shadow = $('<div></div>').css({
position: 'absolute',
'word-wrap': 'break-word',
top: -10000,
left: -10000,
width: $this.width(),
fontSize: $this.css('fontSize'),
fontFamily: $this.css('fontFamily'),
lineHeight: $this.css('lineHeight'),
resize: 'none'
}).appendTo(document.body);
update = function () {
shadow.css('width', $(this).width());
var val = this.value.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/\n/g, '<br/>')
.replace(/\s/g,'&nbsp;');
if (val.indexOf('<br/>', val.length - 5) !== -1) { val += '#'; }
shadow.html(val);
$(this).css('height', Math.max(shadow.height(), minHeight));
};
$this.change(update).keyup(update).keydown(update);
update.apply(this);
});
return this;
};
}(jQuery));

要定义一个自动扩展的文本区域,你必须做两件事:

  1. 单击 Enter key inside it 后,展开 ,或者键入多行内容。
  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);
});

这里有一篇关于这个的文章。

多亏了 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浏览器中进行测试。

你可能会在一些浏览器中看到滚动条的闪烁。

textarea{ overflow:hidden; }

SpYk3HH 收缩尺寸加法编码。

function get_height(elt) {
return elt.scrollHeight + parseFloat($(elt).css("borderTopWidth")) + parseFloat($(elt).css("borderBottomWidth"));
}


$("textarea").keyup(function(e) {
var found = 0;
while (!found) {
$(this).height($(this).height() - 10);
while($(this).outerHeight() < get_height(this)) {
$(this).height($(this).height() + 1);
found = 1;
};
}
});

增长/收缩文本区域。这个演示使用 jQuery 进行事件绑定,但无论如何都不是必须的。 < br > (不支持 IE-IE 不响应 < strong > rows 属性更改)

演示页面


超文本标示语言

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

还有一个非常酷的 bgrins/ExpandingTextareas (github)项目,它是基于 尼尔 · 詹金斯的一个叫做 < strong > 扩展优雅的文字区域 的出版物

我想要动画和自动收缩。这种组合显然很难,因为人们想出了相当激烈的解决方案。我还做了防多纹理的。而且它也没有 jQuery 插件那么重。

我已经基于 vsync 的答案(以及他为此所做的改进) ,http://codepen.io/anon/pen/vlIwj是我改进的代码。

超文本标示语言

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

CSS

body{ background:#728EB2; }


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;
transition:all 1s;
-webkit-transition:all 1s;
}

JS

var rowheight = 0;


$(document).on('input.textarea', '.autoExpand', function(){
var minRows = this.getAttribute('data-min-rows')|0,
rows    = this.value.split("\n").length;
$this = $(this);
var rowz = rows < minRows ? minRows : rows;
var rowheight = $this.attr('data-rowheight');
if(!rowheight){
this.rows = rowz;
$this.attr('data-rowheight', (this.clientHeight  - parseInt($this.css('padding-top')) - parseInt($this.css('padding-bottom')))/ rowz);
}else{
rowz++;
this.style.cssText = 'height:' + rowz * rowheight + 'px';
}
});

有很多答案,但我发现一些非常简单,附加一个 keyup 事件的文本区和检查输入键按键代码是13

keyPressHandler(e){ if(e.keyCode == 13){ e.target.rows = e.target.rows + 1; } }

这将添加另一行到您的文本区,您可以使用 CSS 样式的宽度。

你可以试试这个

$('#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>

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

(这不适用于 Internet Explorer 9或更老版本,因为它使用的是 input事件)

人们似乎有过度工作的解决方案..。

我是这么做的:

  $('textarea').keyup(function()
{
var
$this  = $(this),
height = parseInt($this.css('line-height'),     10),
padTop = parseInt($this.css('padding-top'),     10),
padBot = parseInt($this.css('padding-bottom'),  10);


$this.height(0);


var
scroll = $this.prop('scrollHeight'),
lines  = (scroll  - padTop - padBot) / height;


$this.height(height * lines);
});

这将工作与长线,以及行断开. . 生长和收缩. 。

@ Georgiy Ivankin 在评论中提出了一个建议, 我成功地使用了它:)—— ,但是有一些细微的变化:

$('#note').on('keyup',function(e){
var maxHeight = 200;
var f = document.getElementById('note');
if (f.clientHeight < f.scrollHeight && f.scrollHeight < maxHeight )
{ f.style.height = f.scrollHeight + 'px'; }
});

当它达到200px 的最大高度时就停止扩展

假设你想用 Knokout 来完成这个任务,方法如下:

返回文章页面

<textarea data-bind="event: { keyup: $root.GrowTextArea }"></textarea>

视图模型:

self.GrowTextArea = function (data, event) {
$('#' + event.target.id).height(0).height(event.target.scrollHeight);
}

即使您像我一样使用 Knokout foreach 创建了多个文本区域,这也应该可以工作。

简单的解决方法:

HTML:

<textarea class='expand'></textarea>

约翰逊:

$('textarea.expand').on('input', function() {
$(this).scrollTop($(this).height());
});
$('textarea.expand').scroll(function() {
var h = $(this).scrollTop();
if (h > 0)
$(this).height($(this).height() + h);
});

Https://fiddle.jshell.net/7wsnwbzg/

这对我更有效:

$('.resiText').on('keyup input', function() {
$(this).css('height', 'auto').css('height', this.scrollHeight + (this.offsetHeight - this.clientHeight));
});
.resiText {
box-sizing: border-box;
resize: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea class="resiText"></textarea>

最简单的解决办法是:

Html:

<textarea class="auto-expand"></textarea>

Css:

.auto-expand {
overflow:hidden;
min-height: 80px;
}

Js (jquery) :

$(document).ready(function () {
$("textarea.auto-expand").focus(function () {
var $minHeight = $(this).css('min-height');
$(this).on('input', function (e) {
$(this).css('height', $minHeight);
var $newHeight = $(this)[0].scrollHeight;
$(this).css('height', $newHeight);
});
});
});

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

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:

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

纯 JS 解决方案

function autoSize() {
if (element) {
element.setAttribute('rows', 2) // minimum rows
const rowsRequired = parseInt(
(element.scrollHeight - TEXTAREA_CONFIG.PADDING) / TEXTAREA_CONFIG.LINE_HEIGHT
)
if (rowsRequired !== parseInt(element.getAttribute('rows'))) {
element.setAttribute('rows', rowsRequired)
}
}
}

Https://jsfiddle.net/samb102/cjqa2kf4/54/

这就是我最终使用的解决方案。我想要一个内联的解决方案,到目前为止,这似乎工作得很好:

<textarea onkeyup="$(this).css('height', 'auto').css('height', this.scrollHeight + this.offsetHeight - this.clientHeight);"></textarea>

试试这个:

  $('textarea[name="mytextarea"]').on('input', function(){
$(this).height('auto').height($(this).prop('scrollHeight') + 'px');
});

function autoResizeTextarea() {
for (let index = 0; index < $('textarea').length; index++) {
let element = $('textarea')[index];
let offset = element.offsetHeight - element.clientHeight;
$(element).css('resize', 'none');
$(element).on('input', function() {
$(this).height(0).height(this.scrollHeight - offset - parseInt($(this).css('padding-top')));
});
}
}

Https://codepen.io/nanachi1/pen/rnnkrzq

这应该能行。

简单的 jQuery 解决方案:

$("textarea").keyup(function() {
var scrollHeight = $(this).prop('scrollHeight') - parseInt($(this).css("paddingTop")) - parseInt($(this).css("paddingBottom"));


if (scrollHeight > $(this).height()) {
$(this).height(scrollHeight + "px");
}
});

HTML:

<textarea rows="2" style="padding: 20px; overflow: hidden; resize: none;"></textarea>

溢出 应该是 隐藏。如果不想让鼠标调整它的大小,那么 调整大小就是 没有人

这招对我很管用

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

您可以在所有更改其潜在大小的事件上将 textarea 的高度设置为 scrollHeight:

function setTextareaResponsive(id) {
adjustTextareaHeight(id);


$(window).on("resize", function() {
adjustTextareaHeight(id);
});


$("#" + id).on("change input", function() {
adjustTextareaHeight(id);
});
}


function adjustTextareaHeight(id) {
// set height to 1, so scrollHeight is related to linecount, not original textarea size
$("#" + id).height(1);
$("#" + id).height(document.getElementById(id).scrollHeight);
}

我个人更喜欢它,当高度没有被 scrollHeight 提供的额外高度(通常是12px)填充时。 这就是为什么我喜欢将 height 设置为行数乘以 lineHeight,在这种情况下,调整 TextareaHeight 的函数如下所示:

function adjustTextareaHeight(id) {
var textarea = document.getElementById(id);


// set height to 1, so scrollHeight is related to linecount, not original textarea size
$("#" + id).height(1);
var lineHeight = parseInt(getComputedStyle(textarea).lineHeight)
var numberOfLines = Math.floor(textarea.scrollHeight / lineHeight)
$("#" + id).height(lineHeight * numberOfLines);
}