Відрегулюйте ширину поля введення до його вводу


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

Це мій код, і він не працює. Чи є інший спосіб у HTML, JavaScript, PHP чи CSS встановити мінімальну ширину?

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

Якщо я встановив ширину більше, ніж потрібно, ніж вся програма безладна, мені потрібна ширина 1 пікселя, більше, лише якщо вона потрібна.


Чи відповідає це на ваше запитання? Створення текстової області з автоматичним
зміною

Відповіді:


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, застосованими до деяких атрибутів, проте це протестуйте.
Архонічний

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
Це прекрасно спрацьовує, якщо встановити розмір коробки на вході на "вміст коробки". Таким чином він ігнорує прокладку при встановленні розміру.
Гіперсапієн

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) ширина будь-якого символу не більше 14 пікселів; (2) допустимо, щоб вхідний елемент був розширений на 14 пікселів вище значення елемента. Я додав це до події клавіатури, і це чудово працює!
Натан

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>


Привіт @Michael Ваш код чудово працює, але у мене є проблема. Одне з моїх полів - це поле автозаповнення Google place. І коли я вибираю потрібну адресу зі спадного меню, ширина поля введення не змінюється відповідно до довжини обраної адреси. Чи є це просте виправлення?
Максенсія

2
@Maxence прослуховування changeабо inputподії було б достатньо
січня

У мене виникли проблеми з відображенням діапазону: жодна стилізація не була зареєстрована, оскільки реєстрував діапазон 0 ширини. Краще використовувати абсолютне позиціонування з видимістю: приховано за проміжок.
jayt

Привіт @yarwest, дякую за пораду. Ви будь-яким випадком знаєте, як налаштувати оригінальний сценарій за допомогою цієї установки? (мої знання Js / jquery дуже обмежені)
Maxence

21

Ось рішення, не потребуючи однобічного шрифту , з лише дуже невеликим кодом фрагмента javascript , не потрібно обчислювати обчислювані стилі і, навіть підтримуючи ім'я , підтримувати rtl тексти .

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

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

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

Використовуйте span.textдля підгонки ширини тексту та дозвольте вводу мати однаковий розмір з ним position: absoluteдо контейнера. Скопіюйте значення входу під час spanкожного його зміни (ви можете легко змінити цей фрагмент коду на ванільний js). Тож вхід просто "підходить" за розміром його вмісту.


18

ДЛЯ ПОГЛЯДУВАННЯ ТА ПОЛУЧЕННЯ НІКЕР

Ви повинні використовувати подію jQuery keypress () у поєднанні з String.fromCharCode (наприклад, для отримання натиснутого символу). Отже , ви можете розраховувати , що ваша ширина буде . Чому? Тому що це буде виглядати набагато сексуально :)

Ось jsfiddle, що призводить до приємної поведінки порівняно з рішеннями за допомогою події клавіатури: http://jsfiddle.net/G4FKW/3/

Нижче наводиться ванільний JS, який слухає inputподію <input>елемента та встановлює spanдля того, щоб його вимірювати те саме значення тексту, щоб виміряти його.

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

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

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


1
Виглядає приємно, але він не враховує Backspace та Delete.
Марсель Корпель

Так, для цього вам потрібна подія клавіатури. Ви можете додати певну обробку для зворотного простору та видалити, зробивши це (напр., === 46 для видалення, наприклад, що === 8 для зворотного простору). Але вам все одно потрібна подія натискання клавіші, щоб мати доступ до e.charCode для решти.
Літ

Якщо ви не підтримуєте IE8, ви можете використовувати подію oninput замість перевірки, наприклад: developer.mozilla.org/en-US/docs/Web/Events/input
Frinsh

1
Я відредагував вашу відповідь, щоб усунути jQuery і використовувати лише ванільну JS. майте на увазі, що це рішення далеко не оптимальне, тому що ви хочете загальне рішення, яке не передбачає ручного кодування a spanі css для нього.
vsync

17

Це відповідь, характерна для кутових, але це спрацювало для мене і було дуже задоволенням з точки зору своєї простоти та простоти у використанні:

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

Він автоматично оновлюється за допомогою символьних одиниць у відповіді Яні .


3
Це. Є. Епос.
Daniel

Серйозно. Чарівний.
DongBin Kim

13

Ось альтернативний спосіб вирішити це за допомогою DIV та властивості 'contentedtable':

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, щоб зловити подію подання, щоб ви могли проаналізувати 'значення' ( .innerHTML або .html()відповідно) DIV.


1
Це заслуговує більшої кількості результатів. Це елегантно і просто (якщо використання JS для перевірки форми не є для вас проблемою).
Даніель Боннелл

3
Але це не вхід!
Тоні Мішель Каубе

8

Ви можете встановити ширину введення, використовуючи також атрибут size . Розмір вводу визначає його ширину в символах.

Вхід може динамічно регулювати його розмір, слухаючи ключові події.

Наприклад

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

JsFiddle тут


7

Ви могли б зробити що - щось на зразок цього

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

Сігналы абмеркавання

Сігналы абмеркавання


Якщо збільшити розмір клавіатури, це призведе до некрасивої поведінки. Вхід повинен збільшити його розмір безпосередньо перед тим, як персонаж входить до нього для отримання більшого комфорту.
Літ

5

Просто додавання поверх інших відповідей.

Я помітив, що нині в деяких браузерах поле введення має ширину прокрутки. Що означає:

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

повинні добре працювати. тестується на хром, фаєрфокс та сафарі.

Для підтримки видалення спочатку можна додати "= 0", а потім повторно налаштувати.

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

3
Будь ласка, додайте тут і відповідний код - посилання може бути мертвим у майбутньому, і тоді ця публікація буде марною.
Uooo

3
Це чудово працює, дякую! Я не знаю, чому ця відповідь не має більшої кількості голосів. Це далеко не найпростіший, менш надуманий (js) рішення.
Форма

4

Ось звичайний JS та плагін jQuery, про який я писав, який буде обробляти розмір вхідного елемента за допомогою полотна та розміру / розміру шрифту для визначення фактичної довжини рядка при візуалізації. (працює лише в IE9, chrome, safari, firefox, opera та більшості інших основних браузерів, які реалізували елемент canvas).

PlainJS:

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

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

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

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

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

Плагін jQuery:

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

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

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

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

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

Примітка: це не буде обробляти текстові перетворення, міжрядкові інтервали та проміжки літер, і, можливо, деякі інші властивості зміни розміру тексту. Для обробки набору властивостей перетворення тексту та коригування значення тексту відповідно до цього властивості. Інші, мабуть, досить прямо вперед. Я реалізую, якщо це почне набирати деяку тягу ...


4

Варто зауважити, що красивий розмір можна зробити, коли шрифт є однобічним, тому ми можемо ідеально змінити розмір inputелемента за допомогою chодиниці.

Також у цьому підході ми можемо оновити ширину поля, просто оновивши змінну CSS ( власні властивості ) для inputподії, і ми також повинні подбати про вже попередньо заповнений вхід для DOMContentLoadedподії

Codepen demo


Розмітка

<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

Ця відповідь дає один з найточніших способів пошуку ширини тексту, доступний у браузері, і є більш точним, ніж прийнята відповідь. Він використовує елемент html5 htvas5, і на відміну від інших відповідей не додає елемент у 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; }

Відрегулюйте ширину charW відповідно до ширини вашого шрифту. Здається, це 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 мінімальної ширини . мінімальна ширина зазвичай використовується для визначення мінімальної ширини DOM у макеті рідини, наприклад:

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

Це встановило б вхідний елемент на мінімальну ширину 200 пікселів. У цьому контексті "px" означає "пікселі".

Тепер, якщо ви намагаєтеся перевірити, чи переконайтеся, що поле введення містить хоча б один символ, коли користувач подає його, вам потрібно буде виконати перевірку форми за допомогою JavaScript та PHP. Якщо це дійсно те, що ви намагаєтесь зробити, я відредагую цю відповідь і зроблю все можливе, щоб вам допомогти.


Я знаю, що означає px, і я знаю, що JavaScript має функцію для мінімальної ширини, але він не працює для введення тексту.
Керк

1
@Kerc: "javascript має функцію для мінімальної ширини" - яка? Що ви маєте на увазі? - "це не працює" ніколи не є хорошим описом проблеми. Постарайтеся детальніше розглянути помірковану поведінку.
Марсель Корпель

Ви навіть спробували мій приклад, ніж ви бачите, що це не 1 px, а ваш також. Це не спрацює, незалежно від того, чи напишу це в html, css
Керк

Можливо, для цього є функція php, хтось знає?
Керк

Я спробував ваш приклад, але я припустив, що поле введення в 1 піксель - це не те, що ви шукали. Якщо це так, спробуйте<input type="text" value="1" style="width:1px;" />
peterjmag

1

Мені дуже сподобалась відповідь Літа , але також дуже хотілося, щоб вона:

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

Я адаптував його JSFiddle і придумав це . Одним з покращень у цій скрипці не було б використання чогось на зразок jQuery CSS Parser для фактичного зчитування початкової ширини з правила input.textbox-autosize і використання цього як 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 копійки. Створіть порожній невидимий діл. Заповніть його вмістом і поверніть ширину в поле введення. Збіжіть текстові стилі між кожним полем.

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


1

Досить просто:

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

Де N - це деяке число (2 у прикладі, 17 на щось, що я розробляю), яке визначається експериментально.

Віднімання N запобігає накопиченню цього дивного надмірного простору задовго до того, як текст досягне кінця текстового поля.

Порівняйте. Зверніть пильну увагу на те, як змінюється розмір навіть після першого символу.

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

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


Я не перевіряв багато цього, але ви можете просто змінити oninput='this.style.width = (this.scrollWidth-2) + "px";', oninput='this.style.width = 0; this.style.width = this.scrollWidth + "px";'щоб позбутися місця, що накопичується
MaxCloutier

0

Я просто витрачаю деякий час, з'ясовуючи, як це зробити.
Насправді найпростіший спосіб, який я знайшов, - це перемістити вхідне значення на проміжок безпосередньо перед входом, зберігаючи ширину символу 1. Хоча я не можу бути впевнений, що він відповідає вашим початковим потребам.
Можливо, це якийсь додатковий код, але в застосуванні на основі react + flux це цілком природне рішення.


0

Виходячи з відповіді Майкла, я створив свою власну версію цього за допомогою jQuery. Я думаю, що це більш чистий / коротший варіант більшості відповідей тут, і, здається, вдається виконати роботу.

Я роблю те саме, що і більшість людей тут, використовуючи проліт, щоб записати вхідний текст, а потім отримати ширину. Тоді я встановлюю ширину, коли дії 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 demo

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.