自动缩放输入[type = text]到值的宽度?

Wal*_*ker 77 html css jquery

有没有办法将a的宽度缩放<input type="text">到实际值的宽度?

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

<input type="text" value="me too" />
Run Code Online (Sandbox Code Playgroud)

nra*_*itz 80

您可以通过将size属性设置为输入内容的长度来轻松完成此操作:

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

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

请参阅:http://jsfiddle.net/nrabinowitz/NvynC/

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

  • "右边的填充"不依赖于浏览器,因为元素的大小以字符指定,但对于许多字体而言,并非所有字符都具有相同的宽度.使用可变宽度字体填充"iiiiiiiiiii"字段,您将更清楚地看到问题. (18认同)
  • 很好的代码,我认为最好使用“Courier New”字体作为文本框,因为这种字体中所有字符的宽度都是相等的。(http://jsfiddle.net/NabiKAZ/NvynC/745/) (2认同)

mb2*_*b21 33

如果由于某种原因其他解决方案不适合您,您可以使用contenteditable-span而不是input元素.

<span contenteditable="true">dummy text</span>
Run Code Online (Sandbox Code Playgroud)

请注意,这更像是一种黑客攻击,并且具有允许完全未经过黑名单的HTML输入的严重缺点,例如让用户输入(并粘贴)换行符,链接和其他HTML.

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

更新:你可能想在下面使用Obsidian的解决方案.

  • 用户可以粘贴内容可编辑的换行符.他可以粘贴图像,iframe,几乎任何HTML. (6认同)
  • 这真的是一场灾难 (5认同)
  • 同样粘贴来自MS Word或PDF文件等编辑器的格式化文本会产生意想不到的结果,通常使用它而不是本机输入元素真的很难而且不值得(还). (2认同)
  • `contenteditable`用于设置富文本WYSIWYG文本编辑器.不是为了调整输入大小. (2认同)

Dre*_*TeK 25

一个简单但像素完美的解决方案

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

我设法创建一个像素完美的方式来调整输入宽度,通过一个隐藏的占位符来测量.


jQuery (推荐)

$(function(){
  $('#hide').text($('#txt').val());
  $('#txt').width($('#hide').width());
}).on('input', function () {
  $('#hide').text($('#txt').val());
  $('#txt').width($('#hide').width());
});
Run Code Online (Sandbox Code Playgroud)
body,
#txt,
#hide{
  font:inherit;
  margin:0;
  padding:0;
}
#txt{
  border:none;
  color:#888;
  min-width:10px;
}
#hide{
  display:none;
  white-space:pre;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)


纯JavaScript

我无法确定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";
}
Run Code Online (Sandbox Code Playgroud)
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;
}
Run Code Online (Sandbox Code Playgroud)
<p>Lorem ipsum
  <span id="hide"></span><input id="txt" type="text" value="type here ..."> egestas arcu.
</p>
Run Code Online (Sandbox Code Playgroud)

  • @NightTrain 根据您的要求。添加了 JavaScript 解决方案。=) (3认同)
  • 太棒了!我仍然更愿意在没有 jQuerry 的情况下这样做,而只使用 vanilla JS!这里有一个带有上述代码的 jsfiddle:http://jsfiddle.net/kjxdr50a/ (2认同)

Pio*_*ski 13

我找到了另一个不涉及 JS 的解决方案。在 HTML 中我只是输入了类似的内容:

<div>
  <input class="input" value={someValue} />
  <div class="ghost-input">someValue</div>
</div>
Run Code Online (Sandbox Code Playgroud)

所需要做的就是在 Ghost-input 上设置visibility: hide 和在输入本身上设置 width: 100% 。它之所以有效,是因为输入缩放到其容器的 100%,其宽度由浏览器本身计算(基于相同的文本)。

如果向输入字段添加一些填充和边框,则必须相应地调整 Ghost-input 类(或在输入类中使用 calc() )。

  • 我无法编辑您的答案,因为队列已满,但是如果您将 `display: inline-block` 放在外部 `div` 上,将 `size="1"` 放在输入标记内,它将缩小默认宽度,至少在铬合金中是这样。它并不完美,特别是如果您不删除默认填充,但它对我来说足够接近,并且比这里的任何其他答案容易一百万倍!`.my-input {宽度:100%;} .ghost-input {可见性:隐藏;} .outer-div {显示:内联块;} &lt;input class="my-input" value="小字符串" 大小="1" /&gt; &lt;div class="ghost-input"&gt;小字符串&lt;/div&gt;` (2认同)

Mar*_*lin 9

编辑:该插件现在使用尾随空白字符.谢谢你指出@JavaSpyder

由于大多数其他答案与我所需要的(或根本不起作用)不匹配,我将Adrian B的答案修改为适当的jQuery插件,导致像素完美缩放输入,而无需更改css或html.

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

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

插入:

//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});
Run Code Online (Sandbox Code Playgroud)
<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});
Run Code Online (Sandbox Code Playgroud)


Mar*_*inF 7

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

它反映输入的值,计算宽度并用于设置输入的宽度.

你可以在这里看到一个实例:http://jsfiddle.net/mJMpw/2175/

如何使用它的示例(因为在发布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;    
}
Run Code Online (Sandbox Code Playgroud)

如果你想要一个很好的效果,你只需使用css设置最小/最大宽度并在宽度上使用过渡.

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

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

$("selector").autosizeInput();
Run Code Online (Sandbox Code Playgroud)


dan*_*jar 6

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

<input class="adjust">
Run Code Online (Sandbox Code Playgroud)

输入元素被精确调整像素,并且可以定义附加的偏移.

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);
Run Code Online (Sandbox Code Playgroud)

通过CSS过渡来平滑调整.

.adjust {
    transition: width .15s;
}
Run Code Online (Sandbox Code Playgroud)

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


小智 5

我认为直接使用更准确的 canvas 元素测量宽度更可靠,而不是尝试创建一个 div 并测量其宽度。

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

现在,您可以使用它来测量某个输入元素在任何时间点的宽度应该是多少,方法如下:

// 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);
Run Code Online (Sandbox Code Playgroud)

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

  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";
Run Code Online (Sandbox Code Playgroud)


Arv*_*tad 0

输入元素的行为确实与其他元素不同,如果您提供它们,它们就会做您想要的事情float: left(请参阅http://jsfiddle.net/hEvYj/5/)。我认为如果不使用 JavaScript 以某种方式计算(即在框中每个字母的宽度上添加 5px),这是不可能的。