Отрегулируйте ширину поля ввода для его ввода - 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 ]

4 голосов
/ 01 сентября 2015

Вот простой 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 Plugin:

$.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();

Примечание: это не будет обрабатывать преобразования текста, межстрочный интервал и межбуквенный интервал, а также, возможно, некоторые другие свойства изменения размера текста.Для обработки свойства преобразования текста установите и настройте текстовое значение в соответствии с этим свойством.Другие, вероятно, довольно прямолинейны.Я буду реализовывать, если это начнет набирать обороты ...

3 голосов
/ 02 июля 2013

Просто добавление поверх других ответов.

Я заметил, что в настоящее время в некоторых браузерах поле ввода имеет scrollWidth.Что означает:

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

должно работать хорошо.протестировано в Chrome, Firefox и Safari.

Для поддержки удаления вы можете сначала добавить '= 0', а затем перенастроить.

this.style.width = 0; this.style.width = this.scrollWidth + 'px';
2 голосов
/ 04 июня 2018

Стоит отметить, что при изменении моноширинного шрифта может быть выполнено приятное изменение размера, поэтому мы можем идеально изменить размер элемента input с помощью модуля ch.

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

Демонстрация кодов


Разметка

<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.

2 голосов
/ 09 июля 2018

Если вы используете Bootstrap, это можно сделать очень легко:

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

Вам просто нужно получить содержимое div и поместить его в скрытый ввод перед отправкой формы.

2 голосов
/ 20 июля 2013

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

В вашем 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 с размером шрифта 12px;

1 голос
/ 27 июня 2014

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

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

Я адаптировал его JSFiddle и придумал this . Одним из улучшений, отсутствующих в этой скрипке, было бы использование чего-то вроде 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 голос
/ 03 августа 2010

Я думаю, вы неправильно интерпретируете свойство CSS min-width .min-width обычно используется для определения минимальной ширины DOM в разметке флюида, например:

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

Это установило бы для элемента ввода минимальную ширину 200 пикселей.В этом контексте «px» означает «пиксели».

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

1 голос
/ 16 мая 2018

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

Вот мои 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>
0 голосов
/ 08 января 2016

Я просто потратил некоторое время на выяснение того, как это сделать.
На самом деле самый простой способ, который я нашел, это переместить входное значение в диапазон непосредственно перед входом, сохраняя ширину символа ввода 1.Хотя я не могу быть уверен, что он подходит для вашей первоначальной потребности.
Может быть, это какой-то дополнительный код, но в приложении на основе Reaction + Flux это вполне естественное решение.

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