调整输入字段的宽度为其输入


171
<html>
  <head>
  </head>
  <body>
    <input type="text" value="1" style="min-width:1px;" />
  </body>
</html>

这是我的代码,它不起作用。HTML,JavaScript,PHP或CSS是否有其他方法来设置最小宽度?

我希望文本输入字段的宽度可以动态变化,以便输入字段可以围绕其内容流动。每个输入都有的内置填充2em,这就是问题,第二个问题是min-width根本无法处理输入。

如果我设置的宽度超过了整个程序的混乱程度,那么我需要的宽度是1px,仅在需要时才需要。


这回答了你的问题了吗?创建具有自动调整大小的文本区域
DreamTeK

Answers:


96

听起来您的期望是,根据文本框的内容将样式动态地应用于文本框的宽度。如果是这样,您将需要一些js以在文本框内容更改时运行,如下所示

<input id="txt" type="text" onkeypress="this.style.width = ((this.value.length + 1) * 8) + 'px';">

注意:此解决方案仅在每个字符都非常8px宽时才有效。


41
@Kerc&Tahbaza:是的,但这仅在每个字符的宽度正好为8像素时才起作用。
Marcel Korpel 2010年

6
我同意,Marcel(并且发布的代码并不是我真正看到的用途),但是它展现了所需的行为。您是否知道如何考虑字体,大小,粗细,字距调整等来计算渲染文本的实际宽度?如果是这样,请分享一下,因为我有时会觉得那段代码有用。
塔赫巴扎

1
–我已经认为这只是一个例子。不过,计算输入的宽度并不难。看看我的答案。
Marcel Korpel,2010年

em单位是字符“ m”的宽度。这对于计算字符串的宽度很有用。我已经看到跨浏览器的问题,将em单位应用于某些属性,尽管可以测试。
Archonic

7
您已经忘记了PASTE事件,我的朋友;)您应该将其更改为onInput
vsync

114

在现代浏览器版本中,ch还提供CSS单元。据我了解,它是字体无关的单位,1ch等于0任何给定字体的字符宽度(零)。

因此,可以将以下简单的操作用作调整大小函数:

var input = document.querySelector('input'); // get the input element
input.addEventListener('input', resizeInput); // bind the "resizeInput" callback on "input" event
resizeInput.call(input); // immediately call the function

function resizeInput() {
  this.style.width = this.value.length + "ch";
}
input{ font-size:1.3em; padding:.5em; }
<input>

该示例将“ elem”的大小调整为值的长度+ 2个额外的字符。


13
令我惊讶的是,该评论未获得较高的投票,因为这是一个不错的解决方案,大约95%(1)的浏览器支持此评论。
赫斯基

8
这根本不是一个好的答案,因为测量不准确,并且没有考虑input元素上可能发生的样式,例如font-styleletter-spacing等等。我已经通过现场演示编辑了答案。
vsync

5
如果使用等宽字体,效果很好。对于其他字体,您的里程可能会有所不同,因为它显然使用了0个字符的字符宽度。
吉尔·范古普(Jilles van Gurp),

2
真的很棒 尽管请注意,有时遇到a时,它有时会出错/无法正常运行.
里沙夫

1
如果将输入的框大小设置为“ content-box”,则效果最佳。这样,当您设置尺寸时,它将忽略填充。
Hypersapien

65

要计算当前输入的宽度,您必须将其嵌入一个临时span元素中,将该东西附加到DOM,使用该scrollWidth属性获取计算出的宽度(以像素为单位),然后span再次删除。当然,您必须确保input在和span元素中使用相同的字体系列,字体大小等。因此,我给他们分配了相同的班级。

我将函数附加到keyup事件上,因为keypress尚未将输入字符添加到输入中value,因此将导致错误的宽度。不幸的是,我不知道如何摆脱输入字段的滚动(在字段末尾添加字符时);它会滚动,因为该字符已添加并在adjustWidthOfInput()调用之前显示。而且,如上所述,我无法做到这一点,因为插入按下的字符之前,您将拥有输入字段的值。稍后,我将尝试解决此问题。

顺便说一句,我只在Firefox(3.6.8)中进行了测试,但我希望您会明白这一点。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Get/set width of &lt;input&gt;</title>
    <style>
      body {
        background: #666;
      }

      .input-element {
        border: 0;
        padding: 2px;
        background: #fff;
        font: 12pt sans-serif;
      }

      .tmp-element {
        visibility: hidden;
        white-space: pre;
      }
    </style>
  </head>
  <body>
    <input id="theInput" type="text" class="input-element" value="1">
    <script>
      var inputEl = document.getElementById("theInput");

      function getWidthOfInput() {
        var tmp = document.createElement("span");
        tmp.className = "input-element tmp-element";
        tmp.innerHTML = inputEl.value.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
        document.body.appendChild(tmp);
        var theWidth = tmp.getBoundingClientRect().width;
        document.body.removeChild(tmp);
        return theWidth;
      }

      function adjustWidthOfInput() {
        inputEl.style.width = getWidthOfInput() + "px";
      }

      adjustWidthOfInput();
      inputEl.onkeyup = adjustWidthOfInput;
    </script>
  </body>
</html>

我喜欢您的答案,甚至使用jQuery / Underscore实现了它:gist.github.com/3745941。但是,我可以做一些假设:(1)任何字符的宽度不超过14px,(2)输入元素的长度超出元素值14px是可以接受的。我将其附加到按键事件中,并且效果很好!
弥敦道

11
您应该添加 white-space: pre;到CSS是这样的:.tmp-element{ visibility: hidden; white-space: pre;}。否则,将合并空格,并且宽度计算将失败。<input>并且<span>在空白处理方面有不同的表现,<input>保留空白并将<span>连续的空白合并为一个(如果white-space: pre;未添加)。
TimoKähkönen13年

2
tmp.getBoundingClientRect().width 胜过 tmp.scrollWidth,因为它有时返回0
lisak 2015年

@lisak谢谢,我调整了答案,但是这里已经有更好的答案了。
Marcel Korpel 2015年

更好?我不会这么说。标记的答案缺乏精确度,其他(+这里1这里2)使用jQuery-我不是因为React。画布无法为您提供文字高度AFAIK。想法:空间问题也可以通过以下方式解决:.replace(/ /g, "&nbsp;")
米兰·雅罗斯

30

这是对Lyth答案的修改,其中考虑到了:

  • 删除中
  • 初始化
  • 占位符

它还允许任何数量的输入字段!要查看其实际效果:http : //jsfiddle.net/4Qsa8/

脚本:

$(document).ready(function () {
    var $inputs = $('.resizing-input');

    // Resize based on text if text.length > 0
    // Otherwise resize based on the placeholder
    function resizeForText(text) {
        var $this = $(this);
        if (!text.trim()) {
            text = $this.attr('placeholder').trim();
        }
        var $span = $this.parent().find('span');
        $span.text(text);
        var $inputSize = $span.width();
        $this.css("width", $inputSize);
    }

    $inputs.find('input').keypress(function (e) {
        if (e.which && e.charCode) {
            var c = String.fromCharCode(e.keyCode | e.charCode);
            var $this = $(this);
            resizeForText.call($this, $this.val() + c);
        }
    });

    // Backspace event only fires for keyup
    $inputs.find('input').keyup(function (e) { 
        if (e.keyCode === 8 || e.keyCode === 46) {
            resizeForText.call($(this), $(this).val());
        }
    });

    $inputs.find('input').each(function () {
        var $this = $(this);
        resizeForText.call($this, $this.val())
    });
});

样式:

.resizing-input input, .resizing-input span {
    font-size: 12px;
    font-family: Sans-serif;
    white-space: pre;
    padding: 5px;
}

HTML:

<div class="resizing-input">
    <input type="text" placeholder="placeholder"/>
    <span  style="display:none"></span>
</div>


嗨,迈克尔。您的代码效果很好,但我遇到了问题。我的一个字段是Google place autocmplete字段。当我从下拉菜单中选择正确的地址时,输入字段的宽度不会根据所选地址的长度而改变。有简单的解决方法吗?
Maxence,

2
@Maxence收听changeor input事件就足够了
yarwest

我对跨度的显示有疑问:没有样式,因为它将跨度注册为宽度为0。最好使用具有可见性的绝对定位:隐藏跨度。
jayt

嗨@yarwest,谢谢你的提示。您是否有机会通过此设置来调整原始脚本?(我对Js / jquery的了解非常有限)
Maxence

21

这里是一个解决方案,而不等宽字体需要,用JavaScript只有很小的一块代码不需要计算计算样式,并且,即使是支持输入法支持RTL文本

// copy the text from input to the span
    $(function () {
      $('.input').on('input', function () { $('.text').text($('.input').val()); });
    });
    * {
      box-sizing: border-box;
    }
    
    .container {
      display: inline-block;
      position: relative;
    }
    
    .input,
    .text {
      margin: 0;
      padding: 2px 10px;
      font-size: 24px;
      line-height: 32px;
      border: 1px solid #ccc;
      box-radius: 3px;
      height: 36px;
      font: 20px/20px sans-serif;
      /* font: they should use same font; */
    }

    .text {
      padding-right: 20px;
      display: inline-block;
      visibility: hidden;
      white-space: pre;
    }
    
    .input {
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      width: 100%;
    }
    
<script src="https://code.jquery.com/jquery-3.2.0.min.js"></script>

<div class="container">
  <span class="text">
    some text
  </span>
  <input class="input" value="some text" />
</div>

使用span.text适合文本的宽度,并让输入与position: absolute容器具有相同的大小。将输入值复制到span每次更改时(您可以将这段代码轻松更改为Vanilla js)。因此,输入将仅“适合”其内容的大小。


18

为了让您看起来更好

您应该将jQuery keypress()事件与String.fromCharCode(e.which)结合使用以获取按下的字符。因此,你可以计算出你的宽度是什么。为什么?因为它看起来会更性感:)

与使用keyup事件的解决方案相比,这是一个jsfiddle,它的行为很好:http : //jsfiddle.net/G4FKW/3/

下面是一个普通的JS,它侦听元素的input事件<input>并将span同级设置为具有相同的文本值以便对其进行度量。

document.querySelector('input').addEventListener('input', onInput)

function onInput(){
    var spanElm = this.nextElementSibling;
    spanElm.textContent = this.value; // the hidden span takes the value of the input; 
    this.style.width = spanElm.offsetWidth + 'px'; // apply width of the span to the input
};
/* it's important the input and its span have same styling */
input, .measure {
    padding: 5px;
    font-size: 2.3rem;
    font-family: Sans-serif;
    white-space: pre; /* white-spaces will work effectively */
}

.measure{  
  position: absolute;
  left: -9999px;
  top: -9999px;
}
<input type="text" />
<span class='measure'></span>


1
看起来不错,但没有考虑Backspace和Delete的问题。
Marcel Korpel

是的,为此您需要按键事件。您可以这样做来添加特定的退格处理和删除操作(例如,对于删除而言,=== 46,对于退格来说,等于=== 8)。但是您仍然需要keypress事件来访问其余的e.charCode。
Lyth 2013年

如果您不支持IE8,则可以使用oninput事件代替检查e.which:developer.mozilla.org/en-US/docs/Web/Events/input
Frinsh

1
我已经编辑了您的答案,以消除jQuery,而仅使用普通JS。请注意,此解决方案远非最佳方案,因为您需要一个不涉及手动span为其编码a 和css 的通用解决方案。
vsync


13

这是使用DIV和'contenteditable'属性解决此问题的另一种方法:

HTML:

<div contenteditable = "true" class = "fluidInput" data-placeholder = ""></div>

CSS :(为DIV提供一些尺寸并使其更易于查看)

.fluidInput {

    display         : inline-block;
    vertical-align  : top;

    min-width       : 1em;
    height          : 1.5em;

    font-family     : Arial, Helvetica, sans-serif;
    font-size       : 0.8em;
    line-height     : 1.5em;

    padding         : 0px 2px 0px 2px;
    border          : 1px solid #aaa;
    cursor          : text;
}


.fluidInput * {

    display         : inline;

}


.fluidInput br  {

    display         : none;

}


.fluidInput:empty:before {

    content         : attr(data-placeholder);
    color           : #ccc;

}

注意:如果您打算在打算提交的FORM元素内使用此函数,则需要使用Javascript / jQuery来捕获Submit事件,以便可以解析DIV 的“值”(.innerHTML.html()分别)。


1
这值得更多的投票。它既优雅又简单(只要使用JS进行表单验证对您来说不是问题)。
Daniel Bonnell

3
但这不是输入!
托尼·米歇尔·考贝特

8

您也可以使用size属性设置输入的宽度。输入的大小确定其宽度(以字符为单位)。

输入可以通过侦听关键事件来动态调整其大小。

例如

$("input[type='text']").bind('keyup', function () {
    $(this).attr("size", $(this).val().length );
});

JsFiddle 在这里


7

你可以这样做

// HTML
<input id="input" type="text" style="width:3px" />
// jQuery
$(function(){
  $('#input').keyup(function(){
    $('<span id="width">').append( $(this).val() ).appendTo('body');
    $(this).width( $('#width').width() + 2 );
    $('#width').remove();
  });
});


如果您增加了keyup的大小,将导致难看的行为。为了使角色更加舒适,输入需要在角色进入角色之前增加其大小。
Lyth

5

只需添加其他答案即可。

我注意到,如今在某些浏览器中,输入字段具有scrollWidth。意思是:

this.style.width = this.scrollWidth + 'px';

应该很好地工作。在chrome,firefox和safari中进行了测试。

为了支持删除,您可以先添加“ = 0”,然后再进行调整。

this.style.width = 0; this.style.width = this.scrollWidth + 'px';

3
请在此处也添加相关代码-该链接将来可能会失效,因此此帖子毫无用处。
Uooo

3
这很好,谢谢!我不知道为什么这个答案没有更多的支持。到目前为止,这是最简单,人为较少的(js)解决方案。
表格

4

这是我写的一个普通JS和jQuery插件,它将使用画布和字体大小/字体族来调整输入元素的大小,以确定渲染时的实际字符串长度。(仅适用于IE9,Chrome,Safari,Firefox,Opera和大多数其他实现canvas元素的主流浏览器)。

PlainJS:

function autoSize(input, o) {
    o || (o = {});
    o.on || (o.on = 'keyup');

    var canvas = document.createElement('canvas');
    canvas.setAttribute('style', 'position: absolute; left: -9999px');
    document.body.appendChild(canvas);

    var ctx = canvas.getContext('2d');

    input.addEventListener(o.on, function () {
        ctx.font = getComputedStyle(this,null).getPropertyValue('font');
        this.style.width = ctx.measureText(this.value + '  ').width + 'px';
    });
}

//Usage
autoSize(document.getElementById('my-input'));

jQuery插件:

$.fn.autoSize = function(o) {
  o = $.extend({}, {
    on: 'keyup'
  }, o);

  var $canvas = $('<canvas/>').css({position: 'absolute', left: -9999});
  $('body').append($canvas);

  var ctx = $canvas[0].getContext('2d');

  return this.on(o.on, function(){
    var $this = $(this);
    ctx.font = $this.css('font');
    $this.width(ctx.measureText($this.val()).width + 'px');
  })
}

//Usage:
$('#my-input').autoSize();

注意:这将无法处理文本转换,行间距和字母间距,以及其他可能改变文本大小的属性。要处理文本转换属性,请设置并调整文本值以匹配该属性。其他人可能很直接。如果这开始引起人们的关注,我将实施...


4

值得注意的是,当字体等距时可以完成漂亮的调整大小,因此我们可以input使用ch单位。

此外,在这种方法中,我们可以通过只更新更新域的宽度CSS变量自定义属性的)input事件,我们还应该考虑在已经预先填充输入的关怀DOMContentLoaded活动

Codepen示范


标记

<input type="text" value="space mono font" class="selfadapt" />

的CSS

:root { --size: 0; }

.selfadapt {
   padding: 5px;
   min-width: 10ch;
   font-family: "space mono";
   font-size: 1.5rem;
   width: calc(var(--size) * 1ch);
}

作为根变量,我们设置--size: 0:该变量将包含输入的长度,并将其1chcalc()表达式内部相乘。默认情况下,我们还可以设置最小宽度,例如10ch

Javascript部分读取插入值的长度并更新变量--size

JS

let input = document.querySelector('.selfadapt');
let root  = document.documentElement.style;

/* on input event auto resize the field */
input.addEventListener('input', function() {
   root.setProperty('--size', this.value.length );
});

/* resize the field if it is pre-populated */
document.addEventListener("DOMContentLoaded", function() {
   root.setProperty('--size', input.value.length);
});

当然,即使您不使用等宽字体,这仍然有效,但是在这种情况下,您需要calc()通过将--size变量乘以另一个不同于的值(严格取决于font-familyfont-size)来更改公式1ch


3

此答案提供了一种检索浏览器中可用的文本宽度的最准确方法,并且比公认的答案更准确。它使用canvas html5元素,并且与其他答案不同,它不会将该元素添加到DOM中,从而避免了由于向DOM中过度添加元素而导致的任何重排问题。

在此处阅读更多有关Canvas元素的信息,有关文本宽度。

注意:根据MDN ,该getPropertyValue()方法的简写形式(例如字体)可能不可靠。我建议单独获取值以提高兼容性。我只在这里使用它来提高速度。

/**
 * returns the width of child text of any DOM node as a float
 */
function getTextWidth(el) {
  // uses a cached canvas if available
  var canvas = getTextWidth.canvas || (getTextWidth.canvas = document.createElement("canvas"));
  var context = canvas.getContext("2d");
  // get the full font style property
  var font = window.getComputedStyle(el, null).getPropertyValue('font');
  var text = el.value;
  // set the font attr for the canvas text
  context.font = font;
  var textMeasurement = context.measureText(text);
  return textMeasurement.width;
}

var input = document.getElementById('myInput');
// listen for any input on the input field
input.addEventListener('input', function(e) {
  var width = Math.floor(getTextWidth(e.target));
  // add 10 px to pad the input.
  var widthInPx = (width + 10) + "px";
  e.target.style.width = widthInPx;
}, false);
#myInput {
  font: normal normal 400 normal 18px / normal Roboto, sans-serif;
  min-width: 40px;
}
<input id="myInput" />


2

您可以使用内置的ng-style指令在angularjs中更轻松地完成此操作。

在您的html中:

  <input ng-style="inputStyle(testdata)" ng-model="testdata" />

在您的控制器中:

 $scope.testdata = "whatever";

 $scope.inputStyle = function(str) {
    var charWidth = 7;
    return  {"width": (str.length +1) * charWidth + "px" };
    };

在您的CSS中:

input { font-family:monospace; font-size:12px; }

调整charWidth以匹配字体的宽度。字体大小为12px时似乎为7;


3
这很容易理解,但是向应用程序添加angularjs来动态调整输入元素的大小确实是一个严重的矫kill过正,尤其是当OP要求使用“ HTML,JavaScript,PHP或CSS”解决方案时。有人可能会说jQuery在这方面也是过大的,但是-与Angular不同-作为DOM操纵工具包是jQuery目的的核心。
vlasits 2014年

我应该如何知道所键入字符的宽度?假设它是单色字体并不容易。
伊桑(Ethan)

1
您不需要等宽字体,也不需要Angular。布伦丹的答案基本相同。
Dan Dascalescu 2015年

2

如果您使用Bootstrap,则可以非常轻松地完成此操作:

<div contenteditable="true" class="form-control" style="display: inline"></div>

在提交表单之前,您只需要获取div的内容并将其放在隐藏的输入中即可。


1

我认为您在误解最小宽度CSS属性。min-width通常用于在流体布局中定义最小DOM宽度,例如:

input {
  width: 30%;
  min-width: 200px;
}

这样会将输入元素的最小宽度设置为200像素。在这种情况下,“ px”代表“像素”。

现在,如果您要检查以确保输入字段在用户提交时至少包含一个字符,则需要使用JavaScript和PHP进行某种形式的验证。如果确实是您要这样做,那么我将编辑此答案,并尽最大努力为您提供帮助。


我知道px的意思,我知道javascript具有最小宽度的功能,但不适用于输入文本。
Kerc

1
@Kerc:“ javascript具有最小宽度功能”-哪个?你什么意思?–“它不起作用”永远不是对问题的良好描述。尝试详细说明预期的行为。
马塞尔·科佩尔

您是否还尝试过我的示例,然后您发现它不是1 px,而您也不是。无论我是否用html,css编写,这都
行不通

也许有人为此提供了php函数,有人知道吗?
Kerc

我确实尝试了您的示例,但是我假设1 像素宽的输入字段不是您想要的。如果是这样,请尝试<input type="text" value="1" style="width:1px;" />
peterjmag

1

我非常喜欢Lyth的答案,但也非常希望它能够:

  1. 处理退格键并删除
  2. 不需要您手动添加相邻标签。
  3. 强制最小宽度。
  4. 自动应用于具有特定类的元素

我改编了他的JSFiddle并提出了 这个建议。这个小提琴中没有出现的一项改进是使用jQuery CSS Parser之类的东西从input.textbox-autosize规则中实际读取初始宽度,并将其用作minWidth。正确,我只是在上使用一个属性,该属性可以简化演示,但并不理想。因为它在每个输入上都需要一个额外的属性。您可能还只想在JavaScript中将minWidth设置为100。

HTML:

<div id='applicationHost'>
<div>Name:   <input class='textbox-autosize' data-min-width='100' type="text" /></div>
<div>Email:  <input class='textbox-autosize' data-min-width='100' type="email" /></div>
<div>Points: <input class='textbox-autosize' data-min-width='100' type="number" /></div>
</div>

CSS:

#applicationHost {
    font-family: courier;
    white-space: pre;
}

input.textbox-autosize, span.invisible-autosize-helper {
    padding:0;
    font-size:12px;
    font-family:Sans-serif; 
    white-space:pre;
}
input.textbox-autosize {
    width: 100px; /* Initial width of textboxes */
}

/*
In order for the measurements to work out, your input and the invisible
span need to have the same styling.
*/

JavaScript:

$('#applicationHost').on('keyup', '.textbox-autosize', function(e) {
    // Add an arbitary buffer of 15 pixels.
    var whitespaceBuffer = 15;
    var je = $(this);
    var minWidth = parseInt(je.attr('data-min-width'));
    var newVal = je.val();
    var sizingSpanClass = 'invisible-autosize-helper';
    var $span = je.siblings('span.' + sizingSpanClass).first();
    // If this element hasn't been created yet, we'll create it now.
    if ($span.length === 0) {
        $span = $('<span/>', {
            'class': sizingSpanClass,
            'style': 'display: none;'
        });
        je.parent().append($span);
    }
    $span = je.siblings('span').first();
    $span.text(newVal) ; // the hidden span takes 
    // the value of the input
    $inputSize = $span.width();
    $inputSize += whitespaceBuffer;
    if($inputSize > minWidth)
        je.css("width", $inputSize) ; // apply width of the span to the input
    else
        je.css("width", minWidth) ; // Ensure we're at the min width
});

1

更好的是onvalue

<input id="txt" type="text" onvalue="this.style.width = ((this.value.length + 1) * 8) + 'px';">

它还涉及粘贴,拖放等。


1

这是我的2美分。创建一个空的不可见div。用输入内容填充它,并将宽度返回到输入字段。在每个框之间匹配文本样式。

$(".answers_number").keyup(function(){
    $( "#number_box" ).html( $( this ).val() );
    $( this ).animate({
        width: $( "#number_box" ).width()+20
        }, 300, function() {
    });
});
#number_box {
   position: absolute;
   visibility: hidden;
   height: auto;
   width: auto;
   white-space: nowrap;
   padding:0 4px;
   /*Your font styles to match input*/
   font-family:Arial;
   font-size: 30px; 
}
    
.answers_number {
   font-size: 30px; 
   font-family:Arial;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="number" class="answers_number" />
<div id="number_box">
</div>


1

非常简单:

oninput='this.style.width = (this.scrollWidth - N) + "px";'

其中N是通过实验确定的某个数字(示例中为2,我正在开发的数字为17)。

减去N可防止在文本到达文本框结尾之前很久就积累了这个奇怪的多余空间。

比较。请注意即使仅第一个字符后大小也会如何变化

<p>Subtracting N:</p>    
<input type="text" placeholder="enter lots of text here" oninput='this.style.width = (this.scrollWidth-2) + "px";'>

<p>Not Subtracting N:</p>    
<input type="text" placeholder="enter lots of text here" oninput='this.style.width = (this.scrollWidth) + "px";'>


我没有这种广泛的测试,但你可以只改变oninput='this.style.width = (this.scrollWidth-2) + "px";'通过oninput='this.style.width = 0; this.style.width = this.scrollWidth + "px";'摆脱空间的积累
MaxCloutier

0

我只是花一些时间弄清楚该怎么做。
实际上,我发现的最简单的方法是将输入值移动到恰好在输入之前的跨度,并保持输入1个符号的宽度。虽然我不能确定它是否适合您的最初需求。
也许是一些额外的代码,但是在基于react + flux的应用程序中,这是很自然的解决方案。


0

根据迈克尔的回答,我使用jQuery创建了自己的版本。我认为这是大多数答案的较简洁的版本,似乎可以完成工作。

通过使用跨度将输入文本写入然后获取宽度,我与大多数人在做同样的事情。然后在设置动作keyupblur调用时设置宽度。

这是工作 codepen。该代码笔显示了如何将其与多个输入字段一起使用。

HTML结构:

<input type="text" class="plain-field" placeholder="Full Name">
<span style="display: none;"></span>

jQuery的:

function resizeInputs($text) {
    var text = $text.val().replace(/\s+/g, ' '),
        placeholder = $text.attr('placeholder'),
        span = $text.next('span');
        span.text(placeholder);
    var width = span.width();

    if(text !== '') {
        span.text(text);
    var width = span.width();
    }

    $text.css('width', width + 5);
};

上面的函数获取输入值,修剪多余的空格并将文本设置为span以获取宽度。如果没有文本,则改为获取占位符,然后将其输入到跨度中。一旦将文本输入到跨度中,它将设置输入的宽度。的+ 5上宽度,因为没有了输入被切断的边缘浏览器一点点。

$('.plain-field').each(function() {
    var $text = $(this);
    resizeInputs($text);
});

$('.plain-field').on('keyup blur', function() {
    var $text = $(this);
    resizeInputs($text);
});

$('.plain-field').on('blur', function() {
    var $text = $(this).val().replace(/\s+/g, ' ');
    $(this).val($text);
});

如果可以改进,请告诉我,因为这是我能想到的最干净的解决方案。


0

为什么不只使用CSS?

<div id="wrapper">
  <input onkeyup="keyup(event)">
  <div id="ghost"></div>
</div>

function keyup(e) {
	document.getElementById('ghost').innerText = e.target.value;
}
#wrapper {
  position: relative;
  min-width: 30px;
  display: inline-block;
}

input {
  position: absolute;
  left:0;
  right:0;
  border:1px solid blue;
  width: 100%;
}

#ghost {
  color: transparent;
}
<div id="wrapper">
  <input onkeyup="keyup(event)">
  <div id="ghost"></div>
</div>

wrapper {
  position: relative;
  min-width: 30px;
  border: 1px solid red;
  display: inline-block;
}

input {
  position: absolute;
  left:0;
  right:0;
  width: 100%;
}

#ghost {
  color: transparent;
}

该代码由@Iain Todd引入,我认为我应该分享它


不只是css。这只是另一个js方法。有趣的一个。
vatavale

0

防弹通用方法必须:

  1. 考虑被测元素的所有可能样式input
  2. 无需修改HTML

Codepen示范

var getInputValueWidth = (function(){
  // https://stackoverflow.com/a/49982135/104380
  function copyNodeStyle(sourceNode, targetNode) {
    var computedStyle = window.getComputedStyle(sourceNode);
    Array.from(computedStyle).forEach(key => targetNode.style.setProperty(key, computedStyle.getPropertyValue(key), computedStyle.getPropertyPriority(key)))
  }
  
  function createInputMeassureElm( inputelm ){
    // create a dummy input element for measurements
    var meassureElm = document.createElement('span');
    // copy the read input's styles to the dummy input
    copyNodeStyle(inputelm, meassureElm);
    
    // set hard-coded styles needed for propper meassuring 
    meassureElm.style.width = 'auto';
    meassureElm.style.position = 'absolute';
    meassureElm.style.left = '-9999px';
    meassureElm.style.top = '-9999px';
    meassureElm.style.whiteSpace = 'pre';
    
    meassureElm.textContent = inputelm.value || '';
    
    // add the meassure element to the body
    document.body.appendChild(meassureElm);
    
    return meassureElm;
  }
  
  return function(){
    return createInputMeassureElm(this).offsetWidth;
  }
})();


// delegated event binding
document.body.addEventListener('input', onInputDelegate)

function onInputDelegate(e){
  if( e.target.classList.contains('autoSize') )
    e.target.style.width = getInputValueWidth.call(e.target) + 'px';
}
input{ 
  font-size:1.3em; 
  padding:5px; 
  margin-bottom: 1em;
}

input.type2{
  font-size: 2.5em;
  letter-spacing: 4px;
  font-style: italic;
}
<input class='autoSize' value="type something">
<br>
<input class='autoSize type2' value="here too">


0

您可以只设置size属性。如果您使用的是反应式框架之一,那么下面的内容就足够了:

<input size="{{ yourValue.length }}" [value]="yourValue" />

但是,如果您使用的是纯js,则应设置事件处理程序,例如:

<input oninput="this.setAttribute('size', this.value.length)" />
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.