自动缩放输入[类型=文本]的宽度值?

时间:2022-11-13 22:28:13

Is there a way to scale the width of an <input type="text"> to the width of the actual value?

是否有一种方法可以将的宽度扩展到实际值的宽度?

input {
  display: block;
  margin: 20px;
  width: auto;
}
<input type="text" value="I've had enough of these damn snakes, on this damn plane!" />

<input type="text" value="me too" />

15 个解决方案

#1


73  

You can do this the easy way by setting the size attribute to the length of the input contents:

通过将size属性设置为输入内容的长度,可以很容易地做到这一点:

function resizeInput() {
    $(this).attr('size', $(this).val().length);
}

$('input[type="text"]')
    // event handler
    .keyup(resizeInput)
    // resize on page load
    .each(resizeInput);

See: http://jsfiddle.net/nrabinowitz/NvynC/

参见:http://jsfiddle.net/nrabinowitz/NvynC/

This seems to add some padding on the right that I suspect is browser dependent. If you wanted it to be really tight to the input, you could use a technique like the one I describe in this related answer, using jQuery to calculate the pixel size of your text.

这似乎在右边添加了一些填充,我怀疑是浏览器依赖的。如果您希望它对输入非常严格,您可以使用类似于我在相关答案中描述的技术,使用jQuery来计算文本的像素大小。

#2


33  

If for some reason the other solutions don't work for you, you could use a contenteditable-span instead of an input element.

如果出于某种原因,其他解决方案对您不起作用,您可以使用contenteditable-span而不是输入元素。

<span contenteditable="true">dummy text</span>

Note that this is more of a hack and has the severe drawback of allowing totally unsanitized HTML input like letting users enter (and paste) linebreaks, links and other HTML.

请注意,这更像是一种hack,它有一个严重的缺点,即允许用户输入(和粘贴)linebreak、links和其他HTML等完全未经处理的HTML输入。

So you probably shouldn't use this solution unless you're very carefully sanitising the input...

所以,你可能不应该使用这个解决方案,除非你非常仔细地清理输入……

Update: you probably want to use Obsidian's solution below.

更新:您可能希望使用下面的Obsidian解决方案。

#3


11  

A SIMPLE BUT PIXEL PERFECT SOLUTION

I have seen several ways to do this but calculating the width of fonts isn't always 100% accurate, it's just an estimate.

我已经看到了几种方法,但是计算字体的宽度并不总是100%准确,这只是一个估计。

I managed to create a pixel perfect way of adjusting the input width by having a hidden placeholder to measure from.

我创建了一个像素完美的方法,通过一个隐藏的占位符来测量输入宽度。


jQuery (Recommended)

jQuery(推荐)

$(function(){
  $('#hide').text($('#txt').val());
  $('#txt').width($('#hide').width());
}).on('input', function () {
  $('#hide').text($('#txt').val());
  $('#txt').width($('#hide').width());
});
body,
#txt,
#hide{
  font:inherit;
  margin:0;
  padding:0;
}
#txt{
  border:none;
  color:#888;
  min-width:10px;
}
#hide{
  display:none;
  white-space:pre;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<p>Lorem ipsum 
  <span id="hide"></span><input id="txt" type="text" value="type here ...">
  egestas arcu.
</p>


Pure JavaScript

纯JavaScript

I was unable to determine how jQuery calculates the width of hidden elements so a slight tweak to css was required to accomodate this solution.

我无法确定jQuery是如何计算隐藏元素的宽度的,因此需要对css做一点小小的调整来适应这个解决方案。

var hide = document.getElementById('hide');
var txt = document.getElementById('txt');
resize();
txt.addEventListener("input", resize);

function resize() {
  hide.textContent = txt.value;
  txt.style.width = hide.offsetWidth + "px";
}
body,
#txt,
#hide {
  font: inherit;
  margin: 0;
  padding: 0;
}

#txt {
  border: none;
  color: #888;
  min-width: 10px;
}

#hide {
  position: absolute;
  height: 0;
  overflow: hidden;
  white-space: pre;
}
<p>Lorem ipsum
  <span id="hide"></span><input id="txt" type="text" value="type here ..."> egestas arcu.
</p>

#4


9  

Edit: The plugin now works with trailing whitespace characters. Thanks for pointing it out @JavaSpyder

编辑:插件现在可以使用拖尾空格字符。谢谢你指出@JavaSpyder

Since most other answers didn't match what I needed(or simply didn't work at all) I modified Adrian B's answer into a proper jQuery plugin that results in pixel perfect scaling of input without requiring you to change your css or html.

因为大多数其他的答案都与我所需要的(或者根本不工作)不匹配,所以我将Adrian B的答案修改成一个合适的jQuery插件,这样就可以在不需要修改css或html的情况下实现输入的像素完美缩放。

Example:https://jsfiddle.net/587aapc2/

例如:https://jsfiddle.net/587aapc2/

Usage:$("input").autoresize({padding: 20, minWidth: 20, maxWidth: 300});

用法:美元(“输入”)。autoresize({填充:20,minWidth: 20, maxWidth: 300});

Plugin:

插件:

//JQuery plugin:
$.fn.textWidth = function(_text, _font){//get width of text with font.  usage: $("div").textWidth();
        var fakeEl = $('<span>').hide().appendTo(document.body).text(_text || this.val() || this.text()).css({font: _font || this.css('font'), whiteSpace: "pre"}),
            width = fakeEl.width();
        fakeEl.remove();
        return width;
    };

$.fn.autoresize = function(options){//resizes elements based on content size.  usage: $('input').autoresize({padding:10,minWidth:0,maxWidth:100});
  options = $.extend({padding:10,minWidth:0,maxWidth:10000}, options||{});
  $(this).on('input', function() {
    $(this).css('width', Math.min(options.maxWidth,Math.max(options.minWidth,$(this).textWidth() + options.padding)));
  }).trigger('input');
  return this;
}



//have <input> resize automatically
$("input").autoresize({padding:20,minWidth:40,maxWidth:300});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input value="i magically resize">
<br/><br/>
called with:
$("input").autoresize({padding: 20, minWidth: 40, maxWidth: 300});

#5


6  

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

我在GitHub上有一个jQuery插件:https://github.com/MartinF/jQuery.Autosize.Input

It mirrors the value of the input, calculates the width and uses it for setting the width of the input.

它镜像输入的值,计算宽度并使用它设置输入的宽度。

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

您可以在这里看到一个活生生的例子:http://jsfiddle.net/mJMpw/2175/

Example of how to use it (because some code is needed when posting a jsfiddle link):

如何使用它的示例(因为在发布jsfiddle链接时需要一些代码):

<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.

您只需使用css设置最小/最大宽度,并在需要良好效果的情况下使用宽度的转换。

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.

您可以将到末尾的空间/距离指定为输入元素上的数据自动输入属性的json表示法中的值。

Of course you can also just initialize it using jQuery

当然,您也可以使用jQuery初始化它

$("selector").autosizeInput();

#6


5  

There are already a lot of good answers here. For fun, I implemented this solution below, based on the other answers and my own ideas.

这里已经有很多好的答案了。为了好玩,我在下面基于其他答案和我自己的想法实现了这个解决方案。

<input class="adjust">

The input element is adjusted pixel accurate and an additional offset can be defined.

输入元素被调整为像素精度,可以定义额外的偏移量。

function adjust(elements, offset, min, max) {

    // Initialize parameters
    offset = offset || 0;
    min    = min    || 0;
    max    = max    || Infinity;
    elements.each(function() {
        var element = $(this);

        // Add element to measure pixel length of text
        var id = btoa(Math.floor(Math.random() * Math.pow(2, 64)));
        var tag = $('<span id="' + id + '">' + element.val() + '</span>').css({
            'display': 'none',
            'font-family': element.css('font-family'),
            'font-size': element.css('font-size'),
        }).appendTo('body');

        // Adjust element width on keydown
        function update() {

            // Give browser time to add current letter
            setTimeout(function() {

                // Prevent whitespace from being collapsed
                tag.html(element.val().replace(/ /g, '&nbsp'));

                // Clamp length and prevent text from scrolling
                var size = Math.max(min, Math.min(max, tag.width() + offset));
                if (size < max)
                    element.scrollLeft(0);

                // Apply width to element
                element.width(size);
            }, 0);
        };
        update();
        element.keydown(update);
    });
}

// Apply to our element
adjust($('.adjust'), 10, 100, 500);

The adjustment gets smoothed with a CSS transition.

调整通过CSS转换变得平滑。

.adjust {
    transition: width .15s;
}

Here is the fiddle. I hope this can help others looking for a clean solution.

这是小提琴。我希望这能帮助其他人寻找一个干净的解决方案。

#7


3  

You can solve this problem as here :) http://jsfiddle.net/MqM76/217/

您可以这样解决这个问题:)http://jsfiddle.net/MqM76/217/

HTML:

HTML:

<input id="inpt" type="text" />
<div id="inpt-width"></div>

JS:

JS:

$.fn.textWidth = function(text, font) {
    if (!$.fn.textWidth.fakeEl) $.fn.textWidth.fakeEl =      $('<span>').hide().appendTo(document.body);
    $.fn.textWidth.fakeEl.text(text || this.val() || this.text()).css('font', font || this.css('font'));
    return $.fn.textWidth.fakeEl.width(); 
};

$('#inpt').on('input', function() {
    var padding = 10; //Works as a minimum width
    var valWidth = ($(this).textWidth() + padding) + 'px';
    $('#'+this.id+'-width').html(valWidth);
    $('#inpt').css('width', valWidth);
}).trigger('input');

#8


3  

Unfortunately the size attribute will not work very well. There will be extra space and too little space sometimes, depending on how the font is set up. (check out the example)

不幸的是,size属性不能很好地工作。有时会有额外的空间和太少的空间,这取决于字体的设置方式。(查看)

If you want this to work well, try watching for changes on the input, and resize it then. You probably want to set it to the input's scrollWidth. We would need to account for box sizing, too.

如果您想让它正常工作,请尝试查看输入的更改,然后调整它的大小。您可能希望将其设置为输入的scrollWidth。我们也需要考虑盒子尺寸。

In the following example, I'm setting the size of the input to 1 to prevent it from having a scrollWidth that is greater than our initial width (set manually with CSS).

在下面的示例中,我将输入的大小设置为1,以防止它的滚动宽度大于初始宽度(使用CSS手动设置)。

// (no-jquery document.ready)
function onReady(f) {
    "complete" === document.readyState
        ? f() : setTimeout(onReady, 10, f);
}

onReady(function() {
    [].forEach.call(
        document.querySelectorAll("input[type='text'].autoresize"),
        registerInput
    );
});
function registerInput(el) {
    el.size = 1;
    var style = el.currentStyle || window.getComputedStyle(el),
        borderBox = style.boxSizing === "border-box",
        boxSizing = borderBox
            ? parseInt(style.borderRightWidth, 10) +
                parseInt(style.borderLeftWidth, 10)
            : 0;
    if ("onpropertychange" in el) {
         // IE
         el.onpropertychange = adjust;
    } else if ("oninput" in el) {
         el.oninput = adjust;
    }
    adjust();

    function adjust() {

        // reset to smaller size (for if text deleted) 
        el.style.width = "";

        // getting the scrollWidth should trigger a reflow
        // and give you what the width would be in px if 
        // original style, less any box-sizing
        var newWidth = el.scrollWidth + boxSizing;

        // so let's set this to the new width!
        el.style.width = newWidth + "px";
    }
}
* {
  font-family: sans-serif;
}
input.autoresize {
  width: 125px;
  min-width: 125px;
  max-width: 400px;
}
input[type='text'] {
  box-sizing: border-box;
  padding: 4px 8px;
  border-radius: 4px;
  border: 1px solid #ccc;
  margin-bottom: 10px;
}
<label> 
  Resizes:
  <input class="autoresize" placeholder="this will resize" type='text'>
</label>
<br/>
<label>
  Doesn't resize:
<input placeholder="this will not" type='text'>
</label>
<br/>
<label>
  Has extra space to right:
  <input value="123456789" size="9" type="text"/>
</label>

I think this should work in even IE6, but don't take my word for it.

我认为这在IE6中也应该有效,但是不要相信我的话。

Depending on your use case, you may need to bind the adjust function to other events. E.g. changing an input's value programmatically, or changing the element's style's display property from none (where scrollWidth === 0) to block or inline-block, etc.

根据您的用例,您可能需要将调整函数绑定到其他事件。例如,以编程方式更改输入值,或将元素的样式显示属性从none(其中scrollWidth === 0)更改为block或inline-block等。

#9


3  

Instead of trying to create a div and measure its width, I think it's more reliable to measure the width directly using a canvas element which is more accurate.

与其尝试创建一个div并测量它的宽度,我认为更可靠的方法是使用画布元素直接测量宽度,这样更准确。

function measureTextWidth(txt, font) {
    var element = document.createElement('canvas');
    var context = element.getContext("2d");
    context.font = font;
    return context.measureText(txt).width;
}

Now you can use this to measure what the width of some input element should be at any point in time by doing this:

现在你可以用这个来测量某个输入元素在任意时刻的宽度

// assuming inputElement is a reference to an input element (DOM, not jQuery)
var style = window.getComputedStyle(inputElement, null);
var text = inputElement.value || inputElement.placeholder;
var width = measureTextWidth(text, style.font);

This returns a number (possibly floating point). If you want to account for padding you can try this:

这将返回一个数字(可能是浮点数)。如果你想解释填充物,你可以试试这个:

  var desiredWidth = (parseInt(style.borderLeftWidth) +
      parseInt(style.paddingLeft) +
      Math.ceil(width) +
      1 + // extra space for cursor
      parseInt(style.paddingRight) +
      parseInt(style.borderRightWidth))
  inputElement.style.width = desiredWidth + "px";

#10


1  

My jQuery plugin works for me:

我的jQuery插件适用于我:

Usage:

用法:

    $('form input[type="text"]').autoFit({

    });

Source code of jquery.auto-fit.js:

jquery.auto-fit.js源代码:

;
(function ($) {
    var methods = {
        init: function (options) {
            var settings = $.extend(true, {}, $.fn.autoFit.defaults, options);
            var $this = $(this);

            $this.keydown(methods.fit);

            methods.fit.call(this, null);

            return $this;
        },

        fit: function (event) {
            var $this = $(this);

            var val = $this.val().replace(' ', '-');
            var fontSize = $this.css('font-size');
            var padding = $this.outerWidth() - $this.width();
            var contentWidth = $('<span style="font-size: ' + fontSize + '; padding: 0 ' + padding / 2 + 'px; display: inline-block; position: absolute; visibility: hidden;">' + val + '</span>').insertAfter($this).outerWidth();

            $this.width((contentWidth + padding) + 'px');

            return $this;
        }
    };

    $.fn.autoFit = function (options) {
        if (typeof options == 'string' && methods[options] && typeof methods[options] === 'function') {
            return methods[options].apply(this, Array.prototype.slice.call(arguments, 1));
        } else if (typeof options === 'object' || !options) {
            // Default to 'init'
            return this.each(function (i, element) {
                methods.init.apply(this, [options]);
            });
        } else {
            $.error('Method ' + options + ' does not exist on jquery.auto-fit.');
            return null;
        }
    };

    $.fn.autoFit.defaults = {};

})(this['jQuery']);

#11


0  

Input elements do behave differently from other elements, which would do just about what you want if you give them float: left (see http://jsfiddle.net/hEvYj/5/). I do not think that is possible without calculating it in some way with JavaScript (i.e. add 5px to the width per letter in the box).

输入元素与其他元素的行为是不同的,如果您给它们float: left(请参见http://jsfiddle.net/hEvYj/5/),那么它们的行为就是您想要的。如果不使用JavaScript以某种方式进行计算,我认为这是不可能的(例如,在方框中每个字母的宽度增加5px)。

#12


0  

User nrabinowitz' solution is working great, but I use the keypress event instead of keyup. That reduces the latency if the user types slowly.

用户nrabinowitz的解决方案运行良好,但我使用了keypress事件而不是keyup。如果用户输入缓慢,这将减少延迟。

#13


0  

Here is my modification of nrabinowitz' solution. I didn't use the size property, because it's not perfect with proportional fonts as @Mark noted. My solution place an element after your input and gets width counted by browser (using jQuery).

这是我对nrabinowitz溶液的修改。我没有使用size属性,因为它与比例字体并不完美,@Mark提到过。我的解决方案在您的输入之后放置一个元素,并通过浏览器(使用jQuery)计算宽度。

Although I don't test it, I suppose it will work only if all CSS properties affecting font are inherited.

尽管我没有对它进行测试,但我认为只有继承所有影响字体的CSS属性,它才会工作。

The input width changes on focusout event, which works better for me. But you can use keyup/keypress to change input's width when typing as well.

在focusout事件中,输入宽度发生了变化,这对我来说更好。但是你也可以使用keyup/keypress来改变输入的宽度。

function resizeInput() {

    //Firstly take the content or placeholder if content is missing.
    var content =
        $(this).val().length > 0 ? $(this).val() : $(this).prop("placeholder");

    //Create testing element with same content as input.
    var widthTester = $("<span>"+content+"</span>").hide();

    //Place testing element into DOM after input (so it inherits same formatting as input does).
    widthTester.insertAfter($(this));

    //Set inputs width; you may want to use outerWidth() or innerWidth()
    //depending whether you want to count padding and border or not.
    $(this).css("width",widthTester.width()+"px");

    //Remove the element from the DOM
    widthTester.remove();
 }

 $('.resizing-input').focusout(resizeInput).each(resizeInput);

#14


0  

Using canvas we could calculate the elements width:

使用canvas可以计算元素宽度:

function getTextWidth(text, fontSize, fontName) {
  let canvas = document.createElement('canvas');
  let context = canvas.getContext('2d');
  context.font = fontSize + fontName;
  return context.measureText(text).width;
}

and use it on the chosen event:

并在选定的事件中使用:

function onChange(e) {
  let width = getTextWidth(this.value, $(this).css('font-size'), 
  $(this).css('font-family'));
  $(this.input).css('width', width);
}

#15


0  

try canvas measureText solution

试着帆布measureText解决方案

css:

css:

    input{
        min-width:10px!important;
        max-width:99.99%!important;
        transition: width 0.1s;
        border-width:1px;
    }

javascript:

javascript:

function getWidthOfInput(input){
    var canvas = document.createElement('canvas');
    var ctx = canvas.getContext('2d');
    var text = input.value.length ? input.value : input.placeholder;
    var style = window.getComputedStyle(input);
    ctx.lineWidth = 1;
    ctx.font = style.font;
    var text_width = ctx.measureText(text).width;
    return text_width;
}

function resizable (el, factor) {
    function resize() {
        var width = getWidthOfInput(el);
        el.style.width = width + 'px';
    }
    var e = 'keyup,keypress,focus,blur,change'.split(',');
    for (var i in e){
        el.addEventListener(e[i],resize,false);
    }
    resize();
}

$( "input" ).each( function(i){
    resizable(this);
});

#1


73  

You can do this the easy way by setting the size attribute to the length of the input contents:

通过将size属性设置为输入内容的长度,可以很容易地做到这一点:

function resizeInput() {
    $(this).attr('size', $(this).val().length);
}

$('input[type="text"]')
    // event handler
    .keyup(resizeInput)
    // resize on page load
    .each(resizeInput);

See: http://jsfiddle.net/nrabinowitz/NvynC/

参见:http://jsfiddle.net/nrabinowitz/NvynC/

This seems to add some padding on the right that I suspect is browser dependent. If you wanted it to be really tight to the input, you could use a technique like the one I describe in this related answer, using jQuery to calculate the pixel size of your text.

这似乎在右边添加了一些填充,我怀疑是浏览器依赖的。如果您希望它对输入非常严格,您可以使用类似于我在相关答案中描述的技术,使用jQuery来计算文本的像素大小。

#2


33  

If for some reason the other solutions don't work for you, you could use a contenteditable-span instead of an input element.

如果出于某种原因,其他解决方案对您不起作用,您可以使用contenteditable-span而不是输入元素。

<span contenteditable="true">dummy text</span>

Note that this is more of a hack and has the severe drawback of allowing totally unsanitized HTML input like letting users enter (and paste) linebreaks, links and other HTML.

请注意,这更像是一种hack,它有一个严重的缺点,即允许用户输入(和粘贴)linebreak、links和其他HTML等完全未经处理的HTML输入。

So you probably shouldn't use this solution unless you're very carefully sanitising the input...

所以,你可能不应该使用这个解决方案,除非你非常仔细地清理输入……

Update: you probably want to use Obsidian's solution below.

更新:您可能希望使用下面的Obsidian解决方案。

#3


11  

A SIMPLE BUT PIXEL PERFECT SOLUTION

I have seen several ways to do this but calculating the width of fonts isn't always 100% accurate, it's just an estimate.

我已经看到了几种方法,但是计算字体的宽度并不总是100%准确,这只是一个估计。

I managed to create a pixel perfect way of adjusting the input width by having a hidden placeholder to measure from.

我创建了一个像素完美的方法,通过一个隐藏的占位符来测量输入宽度。


jQuery (Recommended)

jQuery(推荐)

$(function(){
  $('#hide').text($('#txt').val());
  $('#txt').width($('#hide').width());
}).on('input', function () {
  $('#hide').text($('#txt').val());
  $('#txt').width($('#hide').width());
});
body,
#txt,
#hide{
  font:inherit;
  margin:0;
  padding:0;
}
#txt{
  border:none;
  color:#888;
  min-width:10px;
}
#hide{
  display:none;
  white-space:pre;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<p>Lorem ipsum 
  <span id="hide"></span><input id="txt" type="text" value="type here ...">
  egestas arcu.
</p>


Pure JavaScript

纯JavaScript

I was unable to determine how jQuery calculates the width of hidden elements so a slight tweak to css was required to accomodate this solution.

我无法确定jQuery是如何计算隐藏元素的宽度的,因此需要对css做一点小小的调整来适应这个解决方案。

var hide = document.getElementById('hide');
var txt = document.getElementById('txt');
resize();
txt.addEventListener("input", resize);

function resize() {
  hide.textContent = txt.value;
  txt.style.width = hide.offsetWidth + "px";
}
body,
#txt,
#hide {
  font: inherit;
  margin: 0;
  padding: 0;
}

#txt {
  border: none;
  color: #888;
  min-width: 10px;
}

#hide {
  position: absolute;
  height: 0;
  overflow: hidden;
  white-space: pre;
}
<p>Lorem ipsum
  <span id="hide"></span><input id="txt" type="text" value="type here ..."> egestas arcu.
</p>

#4


9  

Edit: The plugin now works with trailing whitespace characters. Thanks for pointing it out @JavaSpyder

编辑:插件现在可以使用拖尾空格字符。谢谢你指出@JavaSpyder

Since most other answers didn't match what I needed(or simply didn't work at all) I modified Adrian B's answer into a proper jQuery plugin that results in pixel perfect scaling of input without requiring you to change your css or html.

因为大多数其他的答案都与我所需要的(或者根本不工作)不匹配,所以我将Adrian B的答案修改成一个合适的jQuery插件,这样就可以在不需要修改css或html的情况下实现输入的像素完美缩放。

Example:https://jsfiddle.net/587aapc2/

例如:https://jsfiddle.net/587aapc2/

Usage:$("input").autoresize({padding: 20, minWidth: 20, maxWidth: 300});

用法:美元(“输入”)。autoresize({填充:20,minWidth: 20, maxWidth: 300});

Plugin:

插件:

//JQuery plugin:
$.fn.textWidth = function(_text, _font){//get width of text with font.  usage: $("div").textWidth();
        var fakeEl = $('<span>').hide().appendTo(document.body).text(_text || this.val() || this.text()).css({font: _font || this.css('font'), whiteSpace: "pre"}),
            width = fakeEl.width();
        fakeEl.remove();
        return width;
    };

$.fn.autoresize = function(options){//resizes elements based on content size.  usage: $('input').autoresize({padding:10,minWidth:0,maxWidth:100});
  options = $.extend({padding:10,minWidth:0,maxWidth:10000}, options||{});
  $(this).on('input', function() {
    $(this).css('width', Math.min(options.maxWidth,Math.max(options.minWidth,$(this).textWidth() + options.padding)));
  }).trigger('input');
  return this;
}



//have <input> resize automatically
$("input").autoresize({padding:20,minWidth:40,maxWidth:300});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input value="i magically resize">
<br/><br/>
called with:
$("input").autoresize({padding: 20, minWidth: 40, maxWidth: 300});

#5


6  

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

我在GitHub上有一个jQuery插件:https://github.com/MartinF/jQuery.Autosize.Input

It mirrors the value of the input, calculates the width and uses it for setting the width of the input.

它镜像输入的值,计算宽度并使用它设置输入的宽度。

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

您可以在这里看到一个活生生的例子:http://jsfiddle.net/mJMpw/2175/

Example of how to use it (because some code is needed when posting a jsfiddle link):

如何使用它的示例(因为在发布jsfiddle链接时需要一些代码):

<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.

您只需使用css设置最小/最大宽度,并在需要良好效果的情况下使用宽度的转换。

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.

您可以将到末尾的空间/距离指定为输入元素上的数据自动输入属性的json表示法中的值。

Of course you can also just initialize it using jQuery

当然,您也可以使用jQuery初始化它

$("selector").autosizeInput();

#6


5  

There are already a lot of good answers here. For fun, I implemented this solution below, based on the other answers and my own ideas.

这里已经有很多好的答案了。为了好玩,我在下面基于其他答案和我自己的想法实现了这个解决方案。

<input class="adjust">

The input element is adjusted pixel accurate and an additional offset can be defined.

输入元素被调整为像素精度,可以定义额外的偏移量。

function adjust(elements, offset, min, max) {

    // Initialize parameters
    offset = offset || 0;
    min    = min    || 0;
    max    = max    || Infinity;
    elements.each(function() {
        var element = $(this);

        // Add element to measure pixel length of text
        var id = btoa(Math.floor(Math.random() * Math.pow(2, 64)));
        var tag = $('<span id="' + id + '">' + element.val() + '</span>').css({
            'display': 'none',
            'font-family': element.css('font-family'),
            'font-size': element.css('font-size'),
        }).appendTo('body');

        // Adjust element width on keydown
        function update() {

            // Give browser time to add current letter
            setTimeout(function() {

                // Prevent whitespace from being collapsed
                tag.html(element.val().replace(/ /g, '&nbsp'));

                // Clamp length and prevent text from scrolling
                var size = Math.max(min, Math.min(max, tag.width() + offset));
                if (size < max)
                    element.scrollLeft(0);

                // Apply width to element
                element.width(size);
            }, 0);
        };
        update();
        element.keydown(update);
    });
}

// Apply to our element
adjust($('.adjust'), 10, 100, 500);

The adjustment gets smoothed with a CSS transition.

调整通过CSS转换变得平滑。

.adjust {
    transition: width .15s;
}

Here is the fiddle. I hope this can help others looking for a clean solution.

这是小提琴。我希望这能帮助其他人寻找一个干净的解决方案。

#7


3  

You can solve this problem as here :) http://jsfiddle.net/MqM76/217/

您可以这样解决这个问题:)http://jsfiddle.net/MqM76/217/

HTML:

HTML:

<input id="inpt" type="text" />
<div id="inpt-width"></div>

JS:

JS:

$.fn.textWidth = function(text, font) {
    if (!$.fn.textWidth.fakeEl) $.fn.textWidth.fakeEl =      $('<span>').hide().appendTo(document.body);
    $.fn.textWidth.fakeEl.text(text || this.val() || this.text()).css('font', font || this.css('font'));
    return $.fn.textWidth.fakeEl.width(); 
};

$('#inpt').on('input', function() {
    var padding = 10; //Works as a minimum width
    var valWidth = ($(this).textWidth() + padding) + 'px';
    $('#'+this.id+'-width').html(valWidth);
    $('#inpt').css('width', valWidth);
}).trigger('input');

#8


3  

Unfortunately the size attribute will not work very well. There will be extra space and too little space sometimes, depending on how the font is set up. (check out the example)

不幸的是,size属性不能很好地工作。有时会有额外的空间和太少的空间,这取决于字体的设置方式。(查看)

If you want this to work well, try watching for changes on the input, and resize it then. You probably want to set it to the input's scrollWidth. We would need to account for box sizing, too.

如果您想让它正常工作,请尝试查看输入的更改,然后调整它的大小。您可能希望将其设置为输入的scrollWidth。我们也需要考虑盒子尺寸。

In the following example, I'm setting the size of the input to 1 to prevent it from having a scrollWidth that is greater than our initial width (set manually with CSS).

在下面的示例中,我将输入的大小设置为1,以防止它的滚动宽度大于初始宽度(使用CSS手动设置)。

// (no-jquery document.ready)
function onReady(f) {
    "complete" === document.readyState
        ? f() : setTimeout(onReady, 10, f);
}

onReady(function() {
    [].forEach.call(
        document.querySelectorAll("input[type='text'].autoresize"),
        registerInput
    );
});
function registerInput(el) {
    el.size = 1;
    var style = el.currentStyle || window.getComputedStyle(el),
        borderBox = style.boxSizing === "border-box",
        boxSizing = borderBox
            ? parseInt(style.borderRightWidth, 10) +
                parseInt(style.borderLeftWidth, 10)
            : 0;
    if ("onpropertychange" in el) {
         // IE
         el.onpropertychange = adjust;
    } else if ("oninput" in el) {
         el.oninput = adjust;
    }
    adjust();

    function adjust() {

        // reset to smaller size (for if text deleted) 
        el.style.width = "";

        // getting the scrollWidth should trigger a reflow
        // and give you what the width would be in px if 
        // original style, less any box-sizing
        var newWidth = el.scrollWidth + boxSizing;

        // so let's set this to the new width!
        el.style.width = newWidth + "px";
    }
}
* {
  font-family: sans-serif;
}
input.autoresize {
  width: 125px;
  min-width: 125px;
  max-width: 400px;
}
input[type='text'] {
  box-sizing: border-box;
  padding: 4px 8px;
  border-radius: 4px;
  border: 1px solid #ccc;
  margin-bottom: 10px;
}
<label> 
  Resizes:
  <input class="autoresize" placeholder="this will resize" type='text'>
</label>
<br/>
<label>
  Doesn't resize:
<input placeholder="this will not" type='text'>
</label>
<br/>
<label>
  Has extra space to right:
  <input value="123456789" size="9" type="text"/>
</label>

I think this should work in even IE6, but don't take my word for it.

我认为这在IE6中也应该有效,但是不要相信我的话。

Depending on your use case, you may need to bind the adjust function to other events. E.g. changing an input's value programmatically, or changing the element's style's display property from none (where scrollWidth === 0) to block or inline-block, etc.

根据您的用例,您可能需要将调整函数绑定到其他事件。例如,以编程方式更改输入值,或将元素的样式显示属性从none(其中scrollWidth === 0)更改为block或inline-block等。

#9


3  

Instead of trying to create a div and measure its width, I think it's more reliable to measure the width directly using a canvas element which is more accurate.

与其尝试创建一个div并测量它的宽度,我认为更可靠的方法是使用画布元素直接测量宽度,这样更准确。

function measureTextWidth(txt, font) {
    var element = document.createElement('canvas');
    var context = element.getContext("2d");
    context.font = font;
    return context.measureText(txt).width;
}

Now you can use this to measure what the width of some input element should be at any point in time by doing this:

现在你可以用这个来测量某个输入元素在任意时刻的宽度

// assuming inputElement is a reference to an input element (DOM, not jQuery)
var style = window.getComputedStyle(inputElement, null);
var text = inputElement.value || inputElement.placeholder;
var width = measureTextWidth(text, style.font);

This returns a number (possibly floating point). If you want to account for padding you can try this:

这将返回一个数字(可能是浮点数)。如果你想解释填充物,你可以试试这个:

  var desiredWidth = (parseInt(style.borderLeftWidth) +
      parseInt(style.paddingLeft) +
      Math.ceil(width) +
      1 + // extra space for cursor
      parseInt(style.paddingRight) +
      parseInt(style.borderRightWidth))
  inputElement.style.width = desiredWidth + "px";

#10


1  

My jQuery plugin works for me:

我的jQuery插件适用于我:

Usage:

用法:

    $('form input[type="text"]').autoFit({

    });

Source code of jquery.auto-fit.js:

jquery.auto-fit.js源代码:

;
(function ($) {
    var methods = {
        init: function (options) {
            var settings = $.extend(true, {}, $.fn.autoFit.defaults, options);
            var $this = $(this);

            $this.keydown(methods.fit);

            methods.fit.call(this, null);

            return $this;
        },

        fit: function (event) {
            var $this = $(this);

            var val = $this.val().replace(' ', '-');
            var fontSize = $this.css('font-size');
            var padding = $this.outerWidth() - $this.width();
            var contentWidth = $('<span style="font-size: ' + fontSize + '; padding: 0 ' + padding / 2 + 'px; display: inline-block; position: absolute; visibility: hidden;">' + val + '</span>').insertAfter($this).outerWidth();

            $this.width((contentWidth + padding) + 'px');

            return $this;
        }
    };

    $.fn.autoFit = function (options) {
        if (typeof options == 'string' && methods[options] && typeof methods[options] === 'function') {
            return methods[options].apply(this, Array.prototype.slice.call(arguments, 1));
        } else if (typeof options === 'object' || !options) {
            // Default to 'init'
            return this.each(function (i, element) {
                methods.init.apply(this, [options]);
            });
        } else {
            $.error('Method ' + options + ' does not exist on jquery.auto-fit.');
            return null;
        }
    };

    $.fn.autoFit.defaults = {};

})(this['jQuery']);

#11


0  

Input elements do behave differently from other elements, which would do just about what you want if you give them float: left (see http://jsfiddle.net/hEvYj/5/). I do not think that is possible without calculating it in some way with JavaScript (i.e. add 5px to the width per letter in the box).

输入元素与其他元素的行为是不同的,如果您给它们float: left(请参见http://jsfiddle.net/hEvYj/5/),那么它们的行为就是您想要的。如果不使用JavaScript以某种方式进行计算,我认为这是不可能的(例如,在方框中每个字母的宽度增加5px)。

#12


0  

User nrabinowitz' solution is working great, but I use the keypress event instead of keyup. That reduces the latency if the user types slowly.

用户nrabinowitz的解决方案运行良好,但我使用了keypress事件而不是keyup。如果用户输入缓慢,这将减少延迟。

#13


0  

Here is my modification of nrabinowitz' solution. I didn't use the size property, because it's not perfect with proportional fonts as @Mark noted. My solution place an element after your input and gets width counted by browser (using jQuery).

这是我对nrabinowitz溶液的修改。我没有使用size属性,因为它与比例字体并不完美,@Mark提到过。我的解决方案在您的输入之后放置一个元素,并通过浏览器(使用jQuery)计算宽度。

Although I don't test it, I suppose it will work only if all CSS properties affecting font are inherited.

尽管我没有对它进行测试,但我认为只有继承所有影响字体的CSS属性,它才会工作。

The input width changes on focusout event, which works better for me. But you can use keyup/keypress to change input's width when typing as well.

在focusout事件中,输入宽度发生了变化,这对我来说更好。但是你也可以使用keyup/keypress来改变输入的宽度。

function resizeInput() {

    //Firstly take the content or placeholder if content is missing.
    var content =
        $(this).val().length > 0 ? $(this).val() : $(this).prop("placeholder");

    //Create testing element with same content as input.
    var widthTester = $("<span>"+content+"</span>").hide();

    //Place testing element into DOM after input (so it inherits same formatting as input does).
    widthTester.insertAfter($(this));

    //Set inputs width; you may want to use outerWidth() or innerWidth()
    //depending whether you want to count padding and border or not.
    $(this).css("width",widthTester.width()+"px");

    //Remove the element from the DOM
    widthTester.remove();
 }

 $('.resizing-input').focusout(resizeInput).each(resizeInput);

#14


0  

Using canvas we could calculate the elements width:

使用canvas可以计算元素宽度:

function getTextWidth(text, fontSize, fontName) {
  let canvas = document.createElement('canvas');
  let context = canvas.getContext('2d');
  context.font = fontSize + fontName;
  return context.measureText(text).width;
}

and use it on the chosen event:

并在选定的事件中使用:

function onChange(e) {
  let width = getTextWidth(this.value, $(this).css('font-size'), 
  $(this).css('font-family'));
  $(this.input).css('width', width);
}

#15


0  

try canvas measureText solution

试着帆布measureText解决方案

css:

css:

    input{
        min-width:10px!important;
        max-width:99.99%!important;
        transition: width 0.1s;
        border-width:1px;
    }

javascript:

javascript:

function getWidthOfInput(input){
    var canvas = document.createElement('canvas');
    var ctx = canvas.getContext('2d');
    var text = input.value.length ? input.value : input.placeholder;
    var style = window.getComputedStyle(input);
    ctx.lineWidth = 1;
    ctx.font = style.font;
    var text_width = ctx.measureText(text).width;
    return text_width;
}

function resizable (el, factor) {
    function resize() {
        var width = getWidthOfInput(el);
        el.style.width = width + 'px';
    }
    var e = 'keyup,keypress,focus,blur,change'.split(',');
    for (var i in e){
        el.addEventListener(e[i],resize,false);
    }
    resize();
}

$( "input" ).each( function(i){
    resizable(this);
});