Dynamically expand height of input type “text” based on number of characters typed into field

后端 未结 3 1227
遇见更好的自我
遇见更好的自我 2020-12-01 10:26

Similar to the below JSFiddle (which I bookmarked and do not know from where the original question emerged):

http://jsfiddle.net/mJMpw/6/



        
相关标签:
3条回答
  • 2020-12-01 10:44

    UPDATED[2]:

    As scrollHeight is always equal to height, we have to set height to '1' before scrollHeight, then when we delete characters the <textarea> autofit:

    $('textarea').on('keydown', function(e){
        if(e.which == 13) {e.preventDefault();}
    }).on('input', function(){
        $(this).height(1);
        var totalHeight = $(this).prop('scrollHeight') - parseInt($(this).css('padding-top')) - parseInt($(this).css('padding-bottom'));
        $(this).height(totalHeight);
    });
    

    Fiddle:

    http://jsfiddle.net/mJMpw/551/

    UPDATED:

    As friends said, <input type="text"/> has no line breaks. My suggest using <textarea> is:

    $('textarea').on({input: function(){
        var totalHeight = $(this).prop('scrollHeight') - parseInt($(this).css('padding-top')) - parseInt($(this).css('padding-bottom'));
        $(this).css({'height':totalHeight});
    }
    });
    

    Fiddle:

    http://jsfiddle.net/mJMpw/548/

    ORIGINAL ANSWER:

    this is very ugly but you could do it like this:

    $('input[type="text"]').on('keyup',function(){
        var text = $(this).val();
        var getWidth = $('<span class="getWidth" style="white-space:nowrap; width:auto;">' + text + '</span>').insertAfter(this);
        $(this).css({'width':getWidth.outerWidth()}).next('.getWidth').remove();
    });
    

    You have to specify the same fonts/padding property to .getWidth and you input:

    input, .getWidth {
        font-family:arial;
        font-size:12px;
        font-weight:normal;
        letter-spacing:normal;
        padding:3px;
    }
    

    Fiddle:

    http://jsfiddle.net/9SMRf/

    0 讨论(0)
  • 2020-12-01 10:47

    Not mine but works great:

    CSS

    textarea {
         color: #444;
         padding: 5px;
    }
    .txtstuff {
        resize: none;
        overflow: hidden;
    }
    .hiddendiv {
        display: none;
        white-space: pre-wrap;
        word-wrap: break-word;
        overflow-wrap: break-word
    }
    .common {
        width: 500px;
        min-height: 50px;
        font-family: Arial, sans-serif;
        font-size: 13px;
        overflow: hidden;
    }
    .lbr {
        line-height: 3px;
    }
    

    HTML

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

    SCRIPT

    let txt = $('#comments'),
        txt.addClass('txtstuff');
    let hiddenDiv = $(document.createElement('div')),
        hiddenDiv.addClass('hiddendiv common');
    let content = null;
    
    $('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());
    });
    

    FIDDLE

    0 讨论(0)
  • 2020-12-01 10:54

    As others explained, input field can't have multiline text, you should use textarea to mimic an input field, and jQuery to make it auto resize vertically (with fixed width).

    JS:

    //This span is used to measure the size of the textarea
    //it should have the same font and text with the textarea and should be hidden
    var span = $('<span>').css('display','inline-block')
                          .css('word-break','break-all')
                          .appendTo('body').css('visibility','hidden');
    function initSpan(textarea){
      span.text(textarea.text())
          .width(textarea.width())
          .css('font',textarea.css('font'));
    }
    $('textarea').on({
        input: function(){
           var text = $(this).val();      
           span.text(text);      
           $(this).height(text ? span.height() : '1.1em');
        },
        focus: function(){           
           initSpan($(this));
        },
        keypress: function(e){
           //cancel the Enter keystroke, otherwise a new line will be created
           //This ensures the correct behavior when user types Enter 
           //into an input field
           if(e.which == 13) e.preventDefault();
        }
    });
    

    CSS:

    textarea {
      width:200px;
      resize:none;
      overflow:hidden;
      font-size:18px;
      height:1.1em;
      padding:2px;
    }
    

    Demo.

    Updated Demo:

    This new updated demo has some bugs fixed and it also supports Enter key, max-height limit, the width does not need to be set fixedly at first (instead we can set its min-width). It's much more full-featured.

    Updated Demo

    0 讨论(0)
提交回复
热议问题