jQuery - 自动调整文本输入框的大小(不是文本区域!)

42

我该如何使用 jQuery 自动调整输入 type="text" 的字段大小?我希望它在开始时宽度为 100 像素,然后随着用户输入文本自动扩展... 这可能吗?


这只用CSS和HTML是不可能实现的吗? - Costa Michailidis
9个回答

64

这里有一个插件可以实现您想要的功能:

该插件:

(function($){

$.fn.autoGrowInput = function(o) {

    o = $.extend({
        maxWidth: 1000,
        minWidth: 0,
        comfortZone: 70
    }, o);

    this.filter('input:text').each(function(){

        var minWidth = o.minWidth || $(this).width(),
            val = '',
            input = $(this),
            testSubject = $('<tester/>').css({
                position: 'absolute',
                top: -9999,
                left: -9999,
                width: 'auto',
                fontSize: input.css('fontSize'),
                fontFamily: input.css('fontFamily'),
                fontWeight: input.css('fontWeight'),
                letterSpacing: input.css('letterSpacing'),
                whiteSpace: 'nowrap'
            }),
            check = function() {

                if (val === (val = input.val())) {return;}

                // Enter new content into testSubject
                var escaped = val.replace(/&/g, '&amp;').replace(/\s/g,' ').replace(/</g, '&lt;').replace(/>/g, '&gt;');
                testSubject.html(escaped);

                // Calculate new width + whether to change
                var testerWidth = testSubject.width(),
                    newWidth = (testerWidth + o.comfortZone) >= minWidth ? testerWidth + o.comfortZone : minWidth,
                    currentWidth = input.width(),
                    isValidWidthChange = (newWidth < currentWidth && newWidth >= minWidth)
                                         || (newWidth > minWidth && newWidth < o.maxWidth);

                // Animate width
                if (isValidWidthChange) {
                    input.width(newWidth);
                }

            };

        testSubject.insertAfter(input);

        $(this).bind('keyup keydown blur update', check);

    });

    return this;

};

})(jQuery);

编辑:找到了:有没有用于文本框的jQuery自动增长插件?


3
这只是一个观察,当粘贴文本时,此插件无法工作,并且还防止用户按下并保持单个键。 - Dennis Plucinik
为什么不直接执行 testSubject.text(val) 而要对 val 进行转义处理呢? - Gautham Badhrinathan
@DennisPlucinik 给 input 事件添加一个绑定应该有助于解决粘贴问题。 - philfreo
9
被踩了 -1 这是某人的回答的完全剪切/粘贴。此外,演示(也不是原帖作者)是使用免费/匿名的 jsbin 账户创建的,已超时 - 不再可用。 请改用 jsFiddle。 - cssyphus

11

我认为这个问题没有完美的解决方案,因为你无法检测输入元素中输入文本的实际宽度。这完全取决于你使用的字体,浏览器中的缩放设置等。

但是,如果你可以选择一种字体,在这种字体下你可以计算出文本占据的像素数量(这是最难的部分,但我认为你可以尝试估计一下)。你可以使用这个来改变你的输入字段的宽度。

 $('input').keyup(function () {
     // I'm assuming that 1 letter will expand the input by 10 pixels
     var oneLetterWidth = 10;

     // I'm also assuming that input will resize when at least five characters
     // are typed
     var minCharacters = 5;
     var len = $(this).val().length;
     if (len > minCharacters) {
         // increase width
         $(this).width(len * oneLetterWidth);
     } else {
         // restore minimal width;
         $(this).width(50);
     }
 });

简洁明了的代码,且能够实际运作,这将让你得到加分! - Vael Victus
1
这个小片段就是我所需要的。我还添加了两个简单的CSS规则,以便用户更好地展开和收缩: 过渡:宽度0.4秒; -webkit-transition:宽度0.4秒;/* Safari */ - Hallgeir Engen

9

(编辑: 使用.text()方法而不是.html()以保证所有格式正确。)

你好,我不知道你是否还在寻找,但我在寻找一个脚本来完成同样的事情时找到了这个。希望这对于任何试图做这个或类似事情的人有所帮助。

function editing_key_press(e){
    if(!e.which)editing_restore(this.parentNode);
    var text = $('<span>')
        .text($(this).val())
        .appendTo(this.parentNode);
    var w = text.innerWidth();
    text.remove();
    $(this).width(w+10);
}

这段代码的逻辑是将内容放在一个 span 中,然后获取该内容的宽度并将其删除。我遇到的问题是必须让它在 keydown 和 keyup 上运行才能成功。

希望这有所帮助,可能不够详细,因为我只学习了很短的时间。

谢谢

George


太完美了!我添加了.hide()到文本中,以防止文本的某个段落一直出现,这样就看不见它了。 - Jason Foglia
2
我喜欢这个,但是当输入空格时它无法工作。 - CoderDennis
为了使其适用于空格,可以在插入虚拟 span 元素之前将所有的“ ”替换为“ ”。 - Simon Steinberger
@SimonSteinberger:使用.text()而不是.html()将解决所有格式问题,并将文本放入span中。我已相应地编辑了答案。 - Yaakov Belch

6
我在GitHub上有一个jQuery插件:https://github.com/MartinF/jQuery.Autosize.Input。它使用了与seize的答案相同的方法,但对评论中提到的一些更改进行了修改。
您可以在这里查看实时示例:http://jsfiddle.net/mJMpw/6/
示例:
<input type="text" value="" placeholder="Autosize" data-autosize-input='{ "space": 40 }' />

input[type="data-autosize-input"] {
  width: 90px;
  min-width: 90px;
  max-width: 300px;
  transition: width 0.25s;    
}

如果想要一个不错的效果,您只需要使用CSS设置最小/最大宽度,并在宽度上使用过渡。

您可以将距离末尾的空间/距离作为JSON表示法中的值指定为输入元素上的data-autosize-input属性。

当然,您也可以使用jQuery进行初始化。

$("selector").autosizeInput();

2
你的 Fiddle 示例在 Chrome 中无法工作 :-( - Lombas
请修复您的Fiddler。 - Seabizkit

2

我使用了seize的答案,但做了以下更改:

  • Between setting isValidWidthChange and // Animate width:

    if (!isValidWidthChange && newWidth > minWidth && newWidth > o.maxWidth) {
        newWidth = o.maxWidth;
        isValidWidthChange = true;
    }
    

    This way the input will grow as big as you've allowed it when its contents are too big to fit within the max width.

  • After $(this).bind('keyup keydown blur update', check);:

    // Auto-size when page first loads
    check();
    

1

Try this code:

var newTextLength = Math.floor($("input#text).val() * .80);
$("input#text").attr("size",newTextLength);

1

看看这个jQuery插件:https://github.com/padolsey/jQuery.fn.autoResize

我刚测试了一下它的文本区域,它可以自动增长。支持文本区域、input[type=text]和input[type=password]。

更新。看起来原作者从github上删除了这个仓库。这个插件已经很久没有更新了,而且有些bug。我之前向这个插件提交了一个pull request,所以我在我的github账户中有它的副本只有在你想要改进它时才使用它,它不是万无一失的!

此外,我发现ExtJS框架对文本字段有自动调整大小的实现,可以查看grow配置属性。虽然从框架中提取这个小逻辑并不容易,但它可以给你一些好的思路。


该链接指向 GitHub 的 404 页面。 - CoderDennis
是的,作者已经删除了它。请查看我的更新答案。 - Dmitry Pashkevich

0

我也在思考同样的问题。文本框应该随着用户输入文本而自动调整大小。虽然我从未使用过它,但我有一个实现的想法。大致如下:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
  <meta http-equiv="content-type" content="text/html; charset=windows-1250">
  <meta name="generator" content="PSPad editor, www.pspad.com">
  <title></title>
  </head>
  <body>

  <table border="1">
  <tr>
    <td>
      <span id="mySpan">
        <span id="mySpan2"></span>
        <input id="myText" type="text" style="width:100%" onkeyup="var span = document.getElementById('mySpan2');var txt = document.getElementById('myText'); span.innerHTML=txt.value;">
       </span>
    </td>
    <td>
            sss
    </td>
  </tr>
</table>

  </body>
</html>

0

默认情况下,输入框的宽度由size参数控制,对于type="text",它对应于应该有多少个字符宽。

由于这是以字符为单位而不是像素为单位进行测量的,因此实际像素大小由使用的(固定宽度)字体控制。


如果您在CSS中为输入设置了宽度,则更改大小参数将不会对实际元素宽度产生任何影响。 - RaYell

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