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


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.