Отрегулируйте ширину поля ввода для его ввода


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

Это мой код, и он не работает. Есть ли другой способ в HTML, JavaScript, PHP или CSS, чтобы установить минимальную ширину?

Я хочу, чтобы поле ввода текста имело динамически изменяющуюся ширину, чтобы поле ввода текло вокруг его содержимого. Каждый вход имеет встроенное заполнение 2em, что является проблемой, а вторая проблема заключается в том, что он min-widthвообще не работает с вводом.

Если я установлю ширину больше, чем нужно, чем вся программа грязная, мне понадобится ширина 1px, больше, только если это необходимо.


Ответы:


96

Похоже, вы ожидаете, что стиль будет применен динамически к ширине текстового поля в зависимости от содержимого текстового поля. Если это так, вам понадобятся некоторые js для запуска при изменении содержимого текстового поля, что-то вроде этого :

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

Примечание: это решение работает только тогда, когда каждый символ достаточно 8pxширокий.


41
@Kerc & Tahbaza: да, но это будет работать, только если ширина каждого символа равна 8 пикселям.
Марсель Корпель

6
Я согласен, Марсель (и опубликованный код не очень полезен для меня), но он демонстрирует желаемое поведение. Знаете ли вы, как рассчитать фактическую ширину отображаемого текста с учетом шрифта, размера, веса, кернинга и т. Д.? Если это так, пожалуйста, поделитесь, как я нашел бы этот фрагмент кода полезным в некоторых случаях.
Тахбаза

1
- Я уже думал, что это только пример. Однако не так сложно рассчитать ширину ввода. Посмотрите на мой ответ.
Марсель Корпель

Единицами 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-style, letter-spacingи так далее. Я отредактировал ответ с живой демонстрацией.
vsync

5
Прекрасно работает, если вы используете моноширинный шрифт. С другими шрифтами ваш пробег может отличаться, поскольку он использует ширину символа 0 символов, очевидно.
Жиль ван Гурп

2
Это действительно здорово. Хотя обратите внимание, что это иногда выдает ошибку / не работает, как я ожидал, когда .встречается.
Ришав

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 после значения элемента. Я прикрепил это к событию keydown, и оно отлично работает!
Натан

11
Вы должны добавить white-space: pre;в CSS следующим образом: .tmp-element{ visibility: hidden; white-space: pre;}. В противном случае пробелы объединяются, и вычисление ширины не выполняется. <input>и <span>ведет себя по-разному в отношении обработки пробелов, <input>сохраняет пробелы и <span>объединяет последовательные пробелы в одно, если white-space: pre;не добавлено.
Тимо Кяхконен,

2
tmp.getBoundingClientRect().widthлучше, чем tmp.scrollWidth, потому что это иногда возвращает 0
Лисак

@lisak Спасибо, я поправил свой ответ, но здесь уже есть лучшие ответы.
Марсель Корпель

Лучше? Я бы так не сказал. Отмеченному ответу не хватает точности, другие (+ здесь 1 и здесь 2 ) используют jQuery - я не из-за React. Холст не может дать вам высоту текста AFAIK. Идея: проблему с пробелами также можно решить с помощью:.replace(/ /g, "&nbsp;")
Милана

30

Вот модификация ответа Лита, которая принимает во внимание:

  • делеция
  • Инициализация
  • Заполнители

Это также позволяет для любого количества полей ввода! Чтобы увидеть это в действии: 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. И когда я выбираю правильный адрес из выпадающего меню, ширина поля ввода не изменяется в зависимости от длины выбранного адреса. Есть ли простое решение для этого?
Максенс

2
@Maxence прослушивания события changeили inputбудет достаточно
yarwest

У меня были проблемы с отображением диапазона: ни одного стиля, поскольку он зарегистрировал диапазон с шириной 0. Лучше использовать абсолютное позиционирование с видимостью: скрыто для пролета.
Джейт

Привет @ 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каждом его изменении (вы можете легко изменить этот фрагмент кода на vanilla js). Таким образом, ввод будет просто «соответствовать» размеру его содержимого.


18

ДЛЯ НИЧЕГО СМОТРЕТЬ И ЧУВСТВОВАТЬ

Вы должны использовать событие jQuery keypress () в сочетании с String.fromCharCode (e.which), чтобы получить нажатый символ. Следовательно, вы можете рассчитать, какой будет ваша ширина . Зачем? Потому что это будет выглядеть намного сексуальнее :)

Вот jsfiddle, который приводит к хорошему поведению по сравнению с решениями, использующими событие keyup: 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.
Марсель Корпель

Да, для этого вам нужно событие keydown. Вы можете добавить определенную обработку для возврата и удаления, выполнив это (например, e.which === 46 для удаления, e.which === 8 для возврата). Но вам все еще нужно событие нажатия клавиши, чтобы иметь доступ к e.charCode для остальных.
Lyth

Если вы не поддерживаете IE8, вы можете использовать событие oninput вместо проверки e.which: developer.mozilla.org/en-US/docs/Web/Events/input
Frinsh

1
Я отредактировал ваш ответ, чтобы исключить jQuery и использовать только vanilla JS. Имейте в виду, что это решение далеко от оптимального, потому что вам нужно универсальное решение, которое не требует ручного кодирования a spanи css для него.
vsync

17

Это специфический для Angular ответ, но он сработал для меня и был очень удовлетворительным с точки зрения его простоты и простоты использования:

<input [style.width.ch]="value.length" [(ngModel)]="value" />

Он автоматически обновляется через символьные единицы в ответе Яни .


3
Это. Является. Эпическая.
Даниэль Флиппанс

Шутки в сторону. Magical.
ДонгБин Ким

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, чтобы вы могли проанализировать «значение» ( .innerHTMLили, .html()соответственно,) DIV.


1
Это заслуживает большего количества голосов. Это элегантно и просто (до тех пор, пока использование JS для проверки формы не является для вас проблемой).
Даниэль Боннелл

3
Но это не вход!
Тони Мишель Каубе

8

Вы можете установить ширину входа, используя размер атрибут . Размер ввода определяет его ширину в символах.

Вход может динамически регулировать его размер, прослушивая ключевые события.

Например

$("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
Пожалуйста, добавьте соответствующий код здесь - ссылка может быть мертвой в будущем, и тогда этот пост бесполезен.
Ууууу

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

Этот ответ обеспечивает один из самых точных методов получения ширины текста, доступных в браузере, и является более точным, чем принятый ответ. Он использует элемент 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

Вы можете сделать это еще проще в angularjs, используя встроенную директиву в стиле ng .

В вашем 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, чтобы соответствовать ширине вашего шрифта. Кажется, что это 7 с размером шрифта 12 пикселей;


3
Это здорово и удобно знать, но добавление angularjs в приложение для динамического изменения размера элемента ввода - это серьезный перебор, особенно когда OP запрашивает решения «HTML, JavaScript, PHP или CSS». Можно утверждать, что jQuery для этого тоже избыточен, но, в отличие от Angular, быть инструментарием для манипулирования DOM является ключевым для цели jQuery.
власит

Как я должен знать ширину набираемого символа? Нелегко предположить, что это шрифт одного размера.
Итан

1
Вы не можете требовать моноширинный шрифт, и нет необходимости в Angular. Ответ Брендана делает в основном то же самое.
Дан Даскалеску

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 пиксель, а ваш тоже нет. Это не сработает, если я напишу это в html, css
Kerc

Возможно, для этого есть функция php, кто-нибудь знает?
Керц

Я попробовал ваш пример, но предположил, что поле ввода шириной в 1 пиксель не то, что вы искали. Если это так, попробуйте<input type="text" value="1" style="width:1px;" />
peterjmag

1

Мне очень понравился ответ Лита , но я также очень хотел:

  1. Обрабатывать возврат и удалить
  2. Не требуется вручную добавлять соседний тег.
  3. Обеспечить минимальную ширину.
  4. Автоматически применяться к элементам с определенным классом

Я адаптировал его JSFiddle и придумал это . Одним из улучшений, отсутствующих в этой скрипке, было бы использование чего-то вроде jQuery CSS Parser для фактического считывания начальной ширины из правила input.textbox-autosize и использования этого в качестве minWidth. Да, я просто использую атрибут для, который делает компактную демонстрацию, но не идеален. поскольку это требует дополнительного атрибута на каждом входе. Вы также можете просто указать minWidth как 100 прямо в JavaScript.

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. Хотя я не могу быть уверен, что он подходит для вашей первоначальной потребности.
Может быть, это какой-то дополнительный код, но в приложении на основе Reaction + Flux это вполне естественное решение.


0

Основываясь на ответе Майкла, я создал свою собственную версию, используя 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. Интересный
Ватавале

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)" />
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.