Отрегулируйте ширину поля ввода для его ввода - PullRequest
137 голосов
/ 03 августа 2010
<html>
  <head>
  </head>
  <body>
    <input type="text" value="1" style="min-width:1px;" />
  </body>
</html>

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

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

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

Ответы [ 24 ]

80 голосов
/ 03 августа 2010

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

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

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

60 голосов
/ 03 августа 2010

Чтобы вычислить ширину текущего ввода, вам нужно встроить его во временный элемент 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>
55 голосов
/ 19 апреля 2017

В современных версиях браузера также доступен модуль CSS ch. Насколько я понимаю, это независимая от шрифта единица, где 1ch равна ширине символа 0 (ноль) в любом данном шрифте.

Таким образом, в качестве функции изменения размера можно использовать что-то простое, например, следующее:

var input = document.querySelector('input'); // get the input element
input.addEventListener('input', resizeInput); // bind the "resizeInput" callback on "input" event
resizeInput.call(input); // immediately call the function

function resizeInput() {
  this.style.width = this.value.length + "ch";
}
input{ font-size:1.3em; padding:.5em; }
<input>

В этом примере будет изменен размер "elem" до длины значения + 2 дополнительных символа.

26 голосов
/ 17 июня 2014

Вот модификация ответа Лита, которая учитывает:

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

Это также позволяетдля любого количества полей ввода!Чтобы увидеть это в действии: 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>

$(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;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="resizing-input">
  First:
  <input type="text" placeholder="placeholder" />
  <span style="display:none"></span>
</div>
<br>
16 голосов
/ 13 февраля 2013

для приятного взгляда и чувства

Вы должны использовать событие 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>
13 голосов
/ 30 декабря 2016

Вот решение без моноширинного шрифта необходимо, только с очень маленьким кусочком кода 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). Таким образом, ввод будет просто «соответствовать» размеру его содержимого.

9 голосов
/ 09 января 2017

Вот альтернативный способ решить эту проблему, используя 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, чтобы перехватить событие отправки, чтобы вы могли проанализировать 'значение' (.innerHTML или .html() соответственно) DIV.

8 голосов
/ 14 февраля 2014

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

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

Например,

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

JsFiddle здесь

7 голосов
/ 03 августа 2010

Вы можете сделать что-то вроде это

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

1006 *

1008 *

6 голосов
/ 08 декабря 2017

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...