入力フィールドの幅をその入力に合わせる


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

これは私のコードであり、機能していません。HTML、JavaScript、PHP、CSSで最小幅を設定する他の方法はありますか?

動的に変化する幅を持つテキスト入力フィールドが必要です。これにより、入力フィールドはそのコンテンツの周囲で流動的になります。すべての入力には、の組み込みパディングがあります2em。これが問題であり、2番目の問題は、min-width入力に対してまったく機能しないことです。

プログラム全体が乱雑になるよりも必要以上に幅を設定した場合、1pxの幅が必要になります(必要な場合のみ)。


これはあなたの質問に答えますか?自動サイズ変更によるテキストエリアの作成
DreamTeK

回答:


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(そして投稿されたコードは私が実際に使用できるものではありません)ですが、それは望ましい動作を示します。フォント、サイズ、太さ、カーニングなどを考慮して、レンダリングされたテキストの実際の幅を計算する方法を知っていますか?その場合は、そのコードが時々役立つと思いますので、共有してください。
Tahbaza

1
–これは一例にすぎないとすでに思っていました。ただし、入力の幅を計算することはそれほど難しくありません。私の答えを見てください。
Marcel Korpel、2010

em単位は、文字「m」の幅です。これは文字列の幅を計算するのに役立ちます。一部の属性に適用されたemユニットでのクロスブラウザーの問題を見てきましたが、テストしてみてください。
Archonic

7
あなたは私の友達のPASTEイベントを忘れました;)あなたはそれをonInput
vsync

114

最新のブラウザバージョンでは、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";
}
input{ font-size:1.3em; padding:.5em; }
<input>

この例では、 "elem"を値の長さ+ 2文字の余分なサイズに変更します。


13
このコメントが優れたソリューションであり、約95%(1)のブラウザーがこれをサポートしているため、このコメントが高く投票されなかったのには驚きです。
ハスキー

8
測定値が正確ではなく、上で発生する可能性のあるアカウントのスタイルになりませんので、これは、すべての良い答えではないinputような要素、font-styleletter-spacingようにと。ライブデモで回答を編集しました。
vsync 2018年

5
等幅フォントを使用する場合に効果的です。他のフォントでは、明らかに0文字の文字幅を使用するため、走行距離が異なる場合があります。
Jilles van Gurp

2
これは本当に素晴らしいです。ただし、バグ.が発生したり、が発生したときに期待どおりに機能しなかったりすることがあります。
リシャフ

1
これは、入力のボックスサイズを 'content-box'に設定すると完全に機能します。これにより、サイズを設定するときにパディングが無視されます。
Hypersapien

65

現在の入力の幅を計算するには、それを一時的なspan要素に埋め込み、それをDOMにアタッチし、scrollWidthプロパティを使用して計算された幅(ピクセル単位)を取得し、span再度削除する必要があります。もちろん、同じフォントファミリー、フォントサイズなどinputspan要素でも要素でも使用されていることを確認する必要があります。したがって、私は彼らに同じクラスを割り当てました。

入力文字がまだinput に追加されていないため、関数をkeyupイベントにアタッチしました。これにより、幅が正しくなくなります。残念ながら、(フィールドの最後に文字を追加する場合)入力フィールドのスクロールを取り除く方法はわかりません。前に文字が追加されて表示されるため、スクロールされます。そして、言ったよう、押された文字が挿入される前に入力フィールドの値を取得するため、これを逆に行うことはできません。この問題は後で解決するようにします。keypressvalueadjustWidthOfInput()

ところで、私はこれを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)input要素が要素の値を超えて14px延長することは許容されます。私はこれをキーダウンイベントにアタッチしましたが、うまくいきます!
ネイサン

11
white-space: pre;次の方法でcssに追加する必要があります.tmp-element{ visibility: hidden; white-space: pre;}。そうでない場合、空白が結合され、幅の計算は失敗します。<input>また<span>、空白の処理に関して異なる動作をし、<input>空白を保持し、追加されない<span>場合white-space: pre;は連続する空白を1つに結合します。
TimoKähkönen2013

2
tmp.getBoundingClientRect().widthそれはtmp.scrollWidth時々0を返すので、より良いです
lisak

@lisakありがとう、私は私の答えを調整しましたが、ここにはすでにより良い答えがあります。
Marcel Korpel、2015年

いい?そうは思いません。マークされた回答は正確性に欠け、他の人(+ ここ1ここ2)はjQueryを使用しています-私はReactのためではありません。キャンバスでは、テキストの高さを確認できません。アイデア:スペースの問題は次の方法でも解決できます:.replace(/ /g, "&nbsp;")
Milan Jaros

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>


@Michaelさん、こんにちは。コードは問題なく機能しますが、問題があります。私のフィールドの1つは、Googleプレイスのautocmpleteフィールドです。ドロップダウンメニューから正しい住所を選択すると、選択した住所の長さに応じて入力フィールドの幅が変更されません。簡単な修正はありますか?
Maxence

2
@Maxenceがchangeor inputイベントをリッスンするだけで十分です
yarwest

スパンが幅0として登録されているため、スパンのdisplay:noneスタイリングに問題がありました。スパンにvisibility:hiddenを指定した絶対配置を使用する方がよい。
jayt

こんにちは@yarwest、ヒントありがとうございます。たぶん、この設定で元のスクリプトを調整する方法を知っていますか?(Js / jqueryに関する私の知識は非常に限られています)
Maxence

21

これは、等幅フォントを必要としないソリューションです。JavaScriptの非常に小さなピースコードのみで計算されたスタイルを計算する必要がなく、さらにimeサポートし、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変更するたびに入力の値をコピーします(このコードを簡単にバニラjsに変更できます)。したがって、入力はそのコンテンツのサイズにちょうど「適合」します。


18

NICER LOOK&FEELの場合

押された文字を取得するには、jQuery keypress()イベントをString.fromCharCode(e.which)と組み合わせて使用​​する必要があります。したがって、幅を計算できますをます。どうして?もっとセクシーに見えるからです:)

ここで素敵な行動の結果は、keyUpイベントを使用したソリューションと比較することをjsfiddleは次のとおりです。http://jsfiddle.net/G4FKW/3/

以下は、要素のinputイベントをリッスンし、兄弟を測定するために同じテキスト値を持つように兄弟を<input>設定するバニラJS 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
見栄えは良いですが、バックスペースと削除は考慮されていません。
Marcel Korpel 2013年

はい、これにはキーダウンイベントが必要です。そうすることで、バックスペースと削除に特定の処理を追加できます(削除の場合はe.which === 46、バックスペースの場合はe.which === 8)。ただし、残りの部分でe.charCodeにアクセスするには、まだkeypressイベントが必要です。
Lyth

IE8をサポートしていない場合は、e.whichをチェックする代わりにoninputイベントを使用できます:developer.mozilla.org/en-US/docs/Web/Events/input
Frinsh

1
私はあなたの答えを編集してjQueryを排除し、バニラJSのみを使用しました。a spanとcssを手動でコーディングする必要がない一般的なソリューションが必要なため、このソリューションは最適とはほど遠いことに注意してください。
vsync 2018年


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を使用して送信イベントをキャッチし、DIV の「値」(.innerHTMLまたは.html()それぞれ)を解析できるようにする必要があります。


1
これは、より多くの賛成投票に値します。エレガントでシンプルです(フォームの検証にJSを使用しても問題ない限り)。
Daniel Bonnell 2017

3
しかし、それは入力ではありません!
Toni Michel Caubet

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();
  });
});


キーアップ時にサイズを大きくすると、醜い動作になります。入力は、より快適にするために、キャラクターが入る直前にサイズを大きくする必要があります。
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 2013

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ます。この変数には入力の長さが含ま1chれ、calc()式の中で乗算されます。デフォルトでは、最小幅を設定することもできます。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-familyとはfont-size異なる別の値(およびに厳密に依存)を掛けて式を変更する必要があります1ch


3

この回答は、ブラウザーで使用可能なテキスト幅を取得する最も正確な方法の1つを提供し、承認された回答よりも正確です。キャンバスの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スタイルのディレクティブを使用して、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を追加することは、特にOPが「HTML、JavaScript、PHP、またはCSS」ソリューションを要求した場合、本当に深刻なやりすぎです。jQueryもこれには過剰だと主張する人もいますが、Angularとは異なり、DOM操作ツールキットであることはjQueryの目的の中核です。
vlasits 2014

入力する文字の幅を知るにはどうすればよいですか?モノサイズのフォントであると想定するのは簡単ではありません。
イーサン

1
等幅フォントは必要ありません。Angularは必要ありません。ブレンダンの答えは基本的に同じです。
Dan Dascalescu、2015

2

ブートストラップを使用すると、非常に簡単に実行できます。

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

フォームを送信する前に、divのコンテンツをフェッチして非表示の入力に入れるだけです。


1

CSSmin-widthプロパティを誤って解釈していると思います。min-widthは通常、次のように流動的なレイアウトの最小DOM幅を定義するために使用されます。

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

これにより、入力要素が最小幅200ピクセルに設定されます。このコンテキストでは、「px」は「ピクセル」を表します。

ここで、ユーザーが入力したときに入力フィールドに少なくとも1つの文字が含まれていることを確認する場合は、JavaScriptとPHPでフォームの検証を行う必要があります。それが本当にあなたがしようとしていることなら、私はこの答えを編集して、あなたを助けるために最善を尽くします。


私はpxの意味を知っており、javascriptにはmin-widthの関数があることを知っていますが、入力テキストに対しては機能しません。
ケルク

1
@Kerc:「javascriptにはmin-widthの機能があります」-どの機能ですか?どういう意味ですか?–「機能しない」は、問題を適切に説明するものではありません。意図した動作について詳しく説明してください。
Marcel Korpel、2010

私の例を試してみましたか?それが1ピクセルではなく、自分の例でもないことがわかります。私はHTML、CSSでそれを書く場合、これは関係なく仕事に行くのではありません
Kerc

多分これのためのphp関数があります、誰でも知っていますか?
ケルク

私はあなたの例を試しましたが、1 ピクセル幅の入力フィールドはあなたが探していたものではないと想定しました。もしそうなら、お試しください<input type="text" value="1" style="width:1px;" />
peterjmag

1

私は本当にLythの答えが好きでしたが、本当にそれを望んでいました:

  1. バックスペースを処理して削除
  2. 隣接するタグを手動で追加する必要はありません。
  3. 最小幅を適用します。
  4. 特定のクラスの要素に自動的に適用されます

私は彼のJSFiddleを適応と思い付いたこの。このフィドルに存在しない改善の1つは、jQuery CSSパーサーのようなものを使用することです。実際に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

Michaelの回答に基づいて、jQueryを使用してこれの独自のバージョンを作成しました。私はこれがほとんどの回答のより簡潔なバージョンであると思います、そしてそれは仕事を成し遂げたようです。

私はここのほとんどの人と同じことをしていますが、スパンを使用して入力テキストを書き込み、幅を取得しています。次に、アクションkeyupと幅を設定しますblur呼び出されるます。

これが実用的なコードペンですです。このコードペンは、これを複数の入力フィールドで使用する方法を示しています。

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);
};

上記の関数は、入力値を取得し、余分なスペースを削除し、テキストをスパンに設定して幅を取得します。テキストがない場合は、代わりにプレースホルダーを取得して、代わりにスパンに入力します。スパンにテキストを入力すると、入力の幅を設定します。+ 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)" />
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.