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

Ker*_*erc 150 html javascript css

<html>
  <head>
  </head>
  <body>
    <input type="text" value="1" style="min-width:1px;" />
  </body>
</html>
Run Code Online (Sandbox Code Playgroud)

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

我想要一个动态变化宽度的文本输入字段,以便输入字段围绕其内容流动.每个输入都有一个内置的填充2em,这就是问题,第二个问题是min-width根本没有输入.

如果我设置宽度超过需要的宽度比整个程序凌乱,我需要1px的宽度,只有在需要时才需要更多.

Tah*_*aza 87

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

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

注意:此解决方案仅适用于每个字符都很8px宽的情况.

  • @Kerc&Tahbaza:是的,但只有当每个角色的宽度恰好是8个像素时,这才有效. (29认同)
  • 我同意,Marcel(并且发布的代码不是我真正可以看到的用途),但它表现出理想的行为.你知道如何计算渲染文本的实际宽度,考虑字体,大小,重量,字距调整等吗?如果是这样,请分享,因为我会发现有时代码有用. (6认同)
  • 你已经忘记了我朋友的**PASTE**事件;)你应该把它改成`onInput` (4认同)

小智 73

在现代浏览器版本中,CSS单元ch也可用.根据我的理解,它是与字体无关的单位,其中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";
}
Run Code Online (Sandbox Code Playgroud)
input{ font-size:1.3em; padding:.5em; }
Run Code Online (Sandbox Code Playgroud)
<input>
Run Code Online (Sandbox Code Playgroud)

该示例将"elem"调整为值+ + 2个字符的长度.

  • 我很惊讶这个评论没有被提高,因为它是一个很好的解决方案,大约95%([1](http://caniuse.com/#search=ch))浏览器支持这一点. (10认同)
  • 如果您使用等宽字体,效果会很好。对于其他字体,您的里程可能会有所不同,因为它显然使用了 0 字符的字符宽度。 (5认同)
  • 这根本不是一个好的答案,因为测量不准确并且没有考虑`input`元素上可能出现的样式,例如`font-style`,`letter-spacing`等等.我用现场演示编辑了答案. (4认同)
  • 如果您将输入上的框大小设置为“content-box”,则效果非常好。这样,当您设置大小时,它会忽略填充。 (3认同)
  • 这真是太棒了。尽管请注意,当遇到“.”时,它有时会出现错误/无法按我的预期工作。 (2认同)

Mar*_*pel 62

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

我将函数附加到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>
Run Code Online (Sandbox Code Playgroud)

  • 你应该将`white-space:pre;`添加到css中:`.tmp-element {visibility:hidden; white-space:pre;}`.否则将合并空格并且宽度计算失败.`<input>`和`<span>`在白空间处理方面表现不同,`<input>`保留空格,`<span>`将连续的空格组合成一个如果`white-space:pre; `没有添加. (9认同)
  • `tmp.getBoundingClientRect().width`优于`tmp.scrollWidth`,因为它有时会返回0 (2认同)

Mic*_*ael 28

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

样式:

.resizing-input input, .resizing-input span {
    font-size: 12px;
    font-family: Sans-serif;
    white-space: pre;
    padding: 5px;
}
Run Code Online (Sandbox Code Playgroud)

HTML:

<div class="resizing-input">
    <input type="text" placeholder="placeholder"/>
    <span  style="display:none"></span>
</div>
Run Code Online (Sandbox Code Playgroud)

$(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())
  });
});
Run Code Online (Sandbox Code Playgroud)
.resizing-input input,
.resizing-input span {
  font-size: 12px;
  font-family: Sans-serif;
  white-space: pre;
  padding: 5px;
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="resizing-input">
  First:
  <input type="text" placeholder="placeholder" />
  <span style="display:none"></span>
</div>
<br>
Run Code Online (Sandbox Code Playgroud)

  • @Maxence监听`change`或`input`事件就足够了 (2认同)

Lyt*_*yth 17

为了一个看起来和感觉

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

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

下面是一个vanilla 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
};
Run Code Online (Sandbox Code Playgroud)
/* 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;
}
Run Code Online (Sandbox Code Playgroud)
<input type="text" />
<span class='measure'></span>
Run Code Online (Sandbox Code Playgroud)

  • 我已经编辑了您的答案以消除 jQuery 并仅使用 vanilla JS。请注意,此解决方案远非最佳,因为您需要一个通用解决方案,该解决方案不涉及为其手动编码 `span` 和 css。 (2认同)

tsh*_*tsh 17

这里是一个解决方案,而不等宽字体需要,用JavaScript只有很小的一块代码,不需要计算计算的风格,而且,甚至支持输入法,支持RTL文本.

// copy the text from input to the span
    $(function () {
      $('.input').on('input', function () { $('.text').text($('.input').val()); });
    });
Run Code Online (Sandbox Code Playgroud)
    * {
      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%;
    }
    
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

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


guy*_*abi 13

只是在其他答案之上添加。

我注意到现在在某些浏览器中,输入字段具有滚动宽度。意思是:

this.style.width = this.scrollWidth + 'px';
Run Code Online (Sandbox Code Playgroud)

应该很好用。在 chrome、firefox 和 safari 中测试。

对于删除支持,您可以先添加'=0',然后重新调整。

this.style.width = 0; this.style.width = this.scrollWidth + 'px';
Run Code Online (Sandbox Code Playgroud)

  • 也请在此处添加相关代码 - 链接将来可能会失效,然后这篇文章就没有用了。 (4认同)
  • 这很好用,谢谢!我不知道为什么这个答案没有更多的赞成票。这是迄今为止最简单、不那么做作的 (js) 解决方案。 (4认同)

log*_*ic8 10

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

HTML:

<div contenteditable = "true" class = "fluidInput" data-placeholder = ""></div>
Run Code Online (Sandbox Code Playgroud)

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;

}
Run Code Online (Sandbox Code Playgroud)

注意:如果您计划在计划提交的FORM元素中使用此元素,则需要使用Javascript/jQuery来捕获submit事件,以便您可以解析DIV 的"值"(.innerHTML.html()分别).

  • 但这不是输入! (3认同)

Chr*_*lde 9

这是特定于Angular的答案,但这对我有用,并且在其简单性和易用性方面非常令人满意:

<input [style.width.ch]="value.length" [(ngModel)]="value" />
Run Code Online (Sandbox Code Playgroud)

它通过Jani的答案中的字符单位自动更新。

  • 对于那些沉迷于框架以至于忘记了本机代码实际上更简单的人来说 `&lt;input oninput="this.style.width=this.value.length+'ch'"&gt;` (10认同)
  • 这。是。史诗。 (6认同)
  • 严重地。神奇。 (3认同)

Mat*_*ent 9

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

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

注意:根据MDNgetPropertyValue(),字体等方法 的速记版本可能不可靠。我建议单独获取这些值以提高兼容性。我只是在这里使用它来提高速度。

/**
 * 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);
Run Code Online (Sandbox Code Playgroud)
#myInput {
  font: normal normal 400 normal 18px / normal Roboto, sans-serif;
  min-width: 40px;
}
Run Code Online (Sandbox Code Playgroud)
<input id="myInput" />
Run Code Online (Sandbox Code Playgroud)

  • 到目前为止最好的答案。高性能且准确。唯一的问题是您可能需要向计算的宽度添加偏移量 (2认同)

bre*_*dan 8

您也可以使用size属性设置输入的宽度.输入的大小决定了它的宽度(以字符为单位).

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

例如

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

JsFiddle 在这里


Tie*_*ies 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();
  });
});
Run Code Online (Sandbox Code Playgroud)


aki*_*nko 6

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

<input size="{{ yourValue.length }}" [value]="yourValue" />
Run Code Online (Sandbox Code Playgroud)

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

<input oninput="this.setAttribute('size', this.value.length)" />

Run Code Online (Sandbox Code Playgroud)


fca*_*ran 5

值得注意的是,当字体为等宽时可以进行漂亮的调整大小,因此我们可以input使用ch单位完美地调整元素的大小。

同样在这种方法中,我们可以通过在事件上更新CSS 变量自定义属性)来更新字段的宽度,input我们还应该处理已经预先填充的DOMContentLoaded事件输入

代码笔演示


标记

<input type="text" value="space mono font" class="selfadapt" />
Run Code Online (Sandbox Code Playgroud)

CSS

:root { --size: 0; }

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

作为根变量,我们设置--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);
});
Run Code Online (Sandbox Code Playgroud)

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