Is there a jQuery autogrow plugin for text fields?

2019-01-02 16:59发布

I have a found various plugins for autogrowing a textarea, but not input text fields. Does anybody know if any exist?

10条回答
时光乱了年华
2楼-- · 2019-01-02 17:42

I have create a plugin for the input of type text, that recreates this behaviour. It has some other unique features. You can see an example and view the documentation of the plugin. @james answer has some problems with pasting large text into the input. To fix it, I have made some modifications to his code. Here is a demo, for this example.

(function($){        
    $.fn.autoGrowInput = function(o) {

        o = $.extend({
            maxWidth: 200,
            minWidth: 1,
            comfortZone: 1,
          width: 1
        }, o);

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

            var minWidth = o.minWidth || $(this).width(),
                maxWidth = o.maxWidth,
                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,'&nbsp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
                    testSubject.html(escaped);

                    // Calculate new width + whether to change
                    var testerWidth = testSubject.width(),
                    newWidth = testerWidth + o.comfortZone,
                    currentWidth = input.width();

                   if (testerWidth < minWidth) {
                       newWidth = minWidth;
                   } else if (testerWidth > maxWidth) {
                       newWidth = maxWidth;
                   } 

                   input.width(newWidth + o.comfortZone);  
            };

            testSubject.insertAfter(input);

            $(this).bind('input', check);

        });

        return this;

    };

})(jQuery);
查看更多
琉璃瓶的回忆
3楼-- · 2019-01-02 17:42

Awsome plugin James ! Thanks. I did add the check suggestion in the end by JP though very effective .

Also I added a some changes on my part. I wanted to set the size for the input to the maximum size if the changed width exceeded the maxWidth so I added :

else if (widthexceeds){
    input.width(o.maxWidth);
}

below the if check for isValidWidthChange where widthexceeds = newWidth > o.maxWidth

查看更多
余生请多指教
4楼-- · 2019-01-02 17:47

Here's a plugin that'll do what you're after:

EDIT: I've fixed the plugin as per Mathias' comment. :)

See a demo here: http://jsfiddle.net/rRHzY

The plugin:

(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,'&nbsp;').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);
查看更多
梦该遗忘
5楼-- · 2019-01-02 17:48

just wanted to share a small improvement to James's great plugin. Add this code to the CSS declaration for the tester element to account for text-indent:

textIndent: 0

Without it, in some situations the tester element may inadvertently inherit the text-indent from elsewhere, thus throwing off the size of the input.

Like JP, I also wanted to resize the input to the correct size from the beginning, which I did just slightly differently, by chaining "trigger('keyup')" to the autoGrowInput method call, e.g.:

$('#contact_form').autoGrowInput({comfortZone: 7, minWidth: 10, maxWidth: 200}).trigger('keyup');

As a side note, I signed up to this site purely to comment on James's solution and I'm a bit annoyed to find that I can't because I don't have enough reputation points to start with. Sorry if I've missed something, but that seems to mean that I have to post this is a comment on the main question rather than more appropriately on James's solution.

查看更多
人气声优
6楼-- · 2019-01-02 17:50

I have a jQuery plugin on GitHub: https://github.com/MartinF/jQuery.Autosize.Input

It uses the same approach as James answer but have some of the changes mentioned in the comments.

You can see an live example here: http://jsfiddle.net/mJMpw/6/

Example:

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

You just use css to set min/max-width and use a transition on the width if you want a nice effect.

You can specify the space / distance to the end as the value in json notation for the data-autosize-input attribute on the input element.

Of course you can also just initialize it using jQuery

$("selector").autosizeInput();
查看更多
初与友歌
7楼-- · 2019-01-02 17:50

Funny enough in IE overflow: visible is taken very seriously. You can achieve this effect by applying overflow: visible on your input elements. Not sure if any similar CSS tricks exist for modern browsers.

查看更多
登录 后发表回答