根据内容自动调整文本区域大小

10
在我的页面上,我有一个文本区域html标签供用户书写信件。我希望文本区域随着每行添加而垂直调整大小,并使下方的内容仅与文本区域底部位置相关。我希望javascript/jquery可以检测到单词换行或添加新行的方式,并基于此对文本区域容器进行调整大小。我的目标是使文本区域下方的内容始终与文本底部保持相同距离,无论用户编写多少内容。当文本溢出时,文本区域会创建滚动条。

插件可以吗?在谷歌上第一个搜索结果是:http://www.jacklmoore.com/autosize/ ,它是基于jQuery的。 - Johannes <- 这个回答被删除了。完美的解决方案,正好符合我的要求。它很简单。 - Ryan Mortensen
4个回答

17

由于我在网上找到的几个解决方案让我不太满意,所以这是我的解决方法。

尊重最小高度和最大高度。 通过向高度添加缓冲区(当前为20,可能替换为行高)来避免跳动和闪烁滚动条。然而,在达到最大高度时仍会显示滚动条。 通过逐步减少文本区域的高度而不是将其设置为0来避免重置容器滚动位置。因此也会一次性删除所有已删除的行。可以在IE和Chrome中正常工作,无需浏览器嗅探。

http://jsfiddle.net/Nd6B3/4/

<textarea id="ta"></textarea>

#ta {
    width:250px;
    min-height:116px;
    max-height:300px;
    resize:none;
}

$("#ta").keyup(function (e) {
    autoheight(this);
});

function autoheight(a) {
    if (!$(a).prop('scrollTop')) {
        do {
            var b = $(a).prop('scrollHeight');
            var h = $(a).height();
            $(a).height(h - 5);
        }
        while (b && (b != $(a).prop('scrollHeight')));
    };
    $(a).height($(a).prop('scrollHeight') + 20);
}

autoheight($("#ta"));

1
不错的解决方案。+1。但我不喜欢while。在我看来,更好的解决方案是:function autoheight(a) { $(a).height(20); $(a).height($(a).prop('scrollHeight') + 20); } - Walery Strauch
1
是的,那样会更加清晰,但不幸的是,当您一次性将高度减少到20时,它将失去其容器(例如body)的滚动位置。 - Thaylon
你刚刚回答了这个困难问题:https://dev59.com/Porda4cB1Zd3GeqPJ0Ll。我会等待你的回答,否则我今晚会发布我的答案。 - gsamaras
这个简单的方法对我来说真是神奇! - Raja
1
到目前为止,我看到的唯一解决方案(包括很多库),不会使滚动条失去位置!谢谢!我一直在寻找一种处理这个问题的方法(通过在“1像素”高度黑客之前插入与文本区域相同高度的div),但是你的解决方案(尽管它有一个while循环)对我来说似乎最干净。 - Dex

10

http://www.jacklmoore.com/autosize/

首先下载插件:

步骤1:将“jquery.autoresize.min.js”放在您的jquery插件存放位置。

步骤2:在HTML中链接文件 -> <script src="jquery.autosize.min.js" type="text/javascript" ></script> 确保此链接出现在您的 jquery 链接之后,且在您自己的 javascript/jquery 代码链接之前。

步骤3:在您的javascript代码文件中添加$('#containerToBeResized').autosize();


1
页面在IE8中甚至无法加载。 - Justin Skiles
1
这个属性尊重 min-heightmax-height - simonzack

3
$('textarea').keyup(function (e) {
    var rows = $(this).val().split("\n");
    $(this).prop('rows', rows.length);
});

这个工作样例的链接:this

4
好的想法,但如果一行比文本区域的宽度更长,则无法实现。 - Walery Strauch
1
$(this).val() -> this.value $(this).prop('rows', rows.length) -> this.rows = this.value.split("\n") - vsync
这是一个工作样例:http://jsfiddle.net/Zu5tY/1/。 - B. Bilgin
仍然存在同样的问题 http://imgur.com/uu5WzHV - Walery Strauch
句子的宽度没有被检查。 - goelakash

1

请看这个Fiddle,来源于这个答案。根据行数增加文本区域的高度。

我想这就是你所需要的。

下面是从答案复制的代码:

HTML

<p>Code explanation: <a href="http://www.impressivewebs.com/textarea-auto-resize/">Textarea Auto Resize</a></p>

<textarea id="comments" placeholder="Type many lines of texts in here and you will see magic stuff" class="common"></textarea>

JS

/*global document:false, $:false */
var txt = $('#comments'),
    hiddenDiv = $(document.createElement('div')),
    content = null;

txt.addClass('txtstuff');
hiddenDiv.addClass('hiddendiv common');

$('body').append(hiddenDiv);

txt.on('keyup', function () {

    content = $(this).val();

    content = content.replace(/\n/g, '<br>');
    hiddenDiv.html(content + '<br class="lbr">');

    $(this).css('height', hiddenDiv.height());

});

CSS
body {
     margin: 20px;
}

p {
    margin-bottom: 14px;
}

textarea {
    color: #444;
    padding: 5px;
}

.txtstuff {
    resize: none; /* remove this if you want the user to be able to resize it in modern browsers */
    overflow: hidden;
}

.hiddendiv {
    display: none;
    white-space: pre-wrap;
    word-wrap: break-word;
    overflow-wrap: break-word; /* future version of deprecated 'word-wrap' */
}

/* the styles for 'commmon' are applied to both the textarea and the hidden clone */
/* these must be the same for both */
.common {
    width: 500px;
    min-height: 50px;
    font-family: Arial, sans-serif;
    font-size: 13px;
    overflow: hidden;
}

.lbr {
    line-height: 3px;
}

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