увеличивать поле ввода текста html при вводе текста?


81

Я могу установить начальный размер ввода текста в css, например:

width: 50px;

Но я бы хотел, чтобы он увеличивался, когда я печатаю, например, до 200 пикселей. Можно ли это сделать в чистом css, html, желательно без javascript?

Разумеется, публикуйте и свои решения js / jquery, но если это можно сделать без них - это будет здорово.

моя попытка здесь:

http://jsfiddle.net/jszjz/2/


Я думаю, этот ТАК вопрос поможет вам: stackoverflow.com/questions/1288297/…
Курт

Для протокола, это не я. Похоже на правильный вопрос, хотя и похожий на тот, который я связал.
Курт

Андре: Постарайтесь, чтобы комментарии были конструктивными.
Сет

1
Вы можете использовать абзац с contenteditable. Он будет расширяться по мере того, как вы печатаете самостоятельно.
Costa

Ответы:


107

Вот пример только с CSS и редактируемым содержимым :

jsFiddle Пример

CSS

span 
{
    border: solid 1px black;
}
div 
{
    max-width: 200px;   
}

HTML

<div>
    <span contenteditable="true">sdfsd</span>
</div>

4
УРА. Я только что пробовал это в IE6-9, последних версиях Opera, Firefox и Chrome - и OMG - он работал везде!
Stann

4
Для меня в Chrome это расширяет элемент вниз по строке, когда он достигает максимальной ширины. Это также не сработает, если ввод должен быть частью формы.
Пол

5
Для многострочного поля ввода (настраиваемые разрывы строк) замените spanна div. Обратите внимание, что word-wrap: break-wordпотребуется или слова длиннее, чем max-widthпереполнят блок div: jsfiddle.net/YZPmC/157
CodeManX 06

6
Убедитесь, что вы очищаете от нежелательного HTML-кода, который может попасть в контентный диапазон путем копирования и вставки.
Брайан Пикок,

3
Это отправляется с формой?
Tomáš Zato - Reinstate Monica

38

Я просто написал это для вас, надеюсь, вам понравится :) Нет гарантий, что это кроссбраузерно, но я думаю, что это так :)

(function(){
    var min = 100, max = 300, pad_right = 5, input = document.getElementById('adjinput');

    input.style.width = min+'px';
    input.onkeypress = input.onkeydown = input.onkeyup = function(){
        var input = this;
        setTimeout(function(){
            var tmp = document.createElement('div');
            tmp.style.padding = '0';
            if(getComputedStyle)
                tmp.style.cssText = getComputedStyle(input, null).cssText;
            if(input.currentStyle)
                tmp.style.cssText = input.currentStyle.cssText;
            tmp.style.width = '';
            tmp.style.position = 'absolute';
            tmp.innerHTML = input.value.replace(/&/g, "&amp;")
                                       .replace(/</g, "&lt;")
                                       .replace(/>/g, "&gt;")
                                       .replace(/"/g, "&quot;")
                                       .replace(/'/g, "&#039;")
                                       .replace(/ /g, '&nbsp;');
            input.parentNode.appendChild(tmp);
            var width = tmp.clientWidth+pad_right+1;
            tmp.parentNode.removeChild(tmp);
            if(min <= width && width <= max)
                input.style.width = width+'px';
        }, 1);
    }
})();

JSFiddle


Спасибо за это. Я решил сделать это с помощью атрибута contenteditable, который не требует js.
Stann

34
«Я только что написал это для тебя». +1 за усилия :)
Кевин Мартин Хосе

Как сделать так, чтобы это нацеливалось на более чем 1 (4) ввод с помощьюid='adjinput'
learntyler

очень креативный, мне это нравится
Дерик

2
Это предполагает, что изменения содержимого происходят только с использованием клавиатуры.
ceving

7

Если вы установите для диапазона display: inline-block, автоматическое изменение размера по горизонтали и вертикали работает очень хорошо:

<span contenteditable="true" 
      style="display: inline-block;
             border: solid 1px black;
             min-width: 50px; 
             max-width: 200px">
</span>


6

Как насчет программного изменения атрибута размера на входе?

Семантически (imo) это решение лучше, чем принятое решение, потому что оно по-прежнему использует поля ввода для пользовательского ввода, но вводит немного jQuery. Soundcloud делает нечто подобное для своих тегов.

<input size="1" />

$('input').on('keydown', function(evt) {
    var $this = $(this),
        size = parseInt($this.attr('size'), 10),
        isValidKey = (evt.which >= 65 && evt.which <= 90) || // a-zA-Z
                     (evt.which >= 48 && evt.which <= 57) || // 0-9
                     evt.which === 32;

    if ( evt.which === 8 && size > 0 ) {
        // backspace
        $this.attr('size', size - 1);
    } else if ( isValidKey ) {
        // all other keystrokes
        $this.attr('size', size + 1);
    }
});

http://jsfiddle.net/Vu9ZT/


2
Это не сработает, если вы выделите текст и нажмете клавишу Backspace, так как он считается только размером-1, а не размером- $ ('input'). Val ().
Length

3
Полагаю, что считать value.lengthбудет и проще, и надежнее.
Томаш Зато - Восстановите Монику

1
Клавиша удаления заставляет это расти
Ricca

3

На ум приходит пара вещей:

Используйте onkeydownобработчик в текстовом поле, измерьте текст * и соответственно увеличьте размер текстового поля.

Прикрепите :focus к текстовому полю класс css большей ширины. Тогда ваша коробка будет больше, когда сфокусирована. Это не совсем то, о чем вы просите, но похоже.

* Измерять текст в javascript непросто. Ознакомьтесь с этим вопросом, чтобы получить некоторые идеи.


лучший ответ на данный момент. :focus { width: 100% }
oldboy

3

От: Есть ли плагин jQuery autogrow для текстовых полей?


Смотрите демонстрацию здесь: http://jsbin.com/ahaxe

Плагин:

(function($){

    $.fn.autoGrowInput = function(o) {

        o = $.extend({
            maxWidth: 1000,
            minWidth: 0,
            comfortZone: 70
        }, o);

        this.filter('input:text').each(function(){

            var minWidth = o.minWidth || $(this).width(),
                val = '',
                input = $(this),
                testSubject = $('<tester/>').css({
                    position: 'absolute',
                    top: -9999,
                    left: -9999,
                    width: 'auto',
                    fontSize: input.css('fontSize'),
                    fontFamily: input.css('fontFamily'),
                    fontWeight: input.css('fontWeight'),
                    letterSpacing: input.css('letterSpacing'),
                    whiteSpace: 'nowrap'
                }),
                check = function() {

                    if (val === (val = input.val())) {return;}

                    // Enter new content into testSubject
                    var escaped = val.replace(/&/g, '&amp;').replace(/\s/g,'&nbsp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
                    testSubject.html(escaped);

                    // Calculate new width + whether to change
                    var testerWidth = testSubject.width(),
                        newWidth = (testerWidth + o.comfortZone) >= minWidth ? testerWidth + o.comfortZone : minWidth,
                        currentWidth = input.width(),
                        isValidWidthChange = (newWidth < currentWidth && newWidth >= minWidth)
                                             || (newWidth > minWidth && newWidth < o.maxWidth);

                    // Animate width
                    if (isValidWidthChange) {
                        input.width(newWidth);
                    }

                };

            testSubject.insertAfter(input);

            $(this).bind('keyup keydown blur update', check);

        });

        return this;

    };

})(jQuery);

2

Здесь вы можете попробовать что-то вроде этого

РЕДАКТИРОВАТЬ: ПЕРЕСМОТРЕННЫЙ ПРИМЕР (добавлено одно новое решение) http://jsfiddle.net/jszjz/10/

Объяснение кода

var jqThis = $('#adjinput'), //object of the input field in jQuery
    fontSize = parseInt( jqThis.css('font-size') ) / 2, //its font-size
    //its min Width (the box won't become smaller than this
    minWidth= parseInt( jqThis.css('min-width') ), 
    //its maxWidth (the box won't become bigger than this)
    maxWidth= parseInt( jqThis.css('max-width') );

jqThis.bind('keydown', function(e){ //on key down
   var newVal = (this.value.length * fontSize); //compute the new width

   if( newVal  > minWidth && newVal <= maxWidth ) //check to see if it is within Min and Max
       this.style.width = newVal + 'px'; //update the value.
});

и css тоже довольно прост

#adjinput{
    max-width:200px !important;
    width:40px;
    min-width:40px;
    font-size:11px;
}

РЕДАКТИРОВАТЬ: Другое решение - заставить пользователя ввести то, что он хочет, и при размытии (фокусировка), захватить строку (с тем же размером шрифта), поместить ее в div - подсчитать ширину div - а затем с красивой анимацией с классным Эффект ослабления обновляет ширину полей ввода. Единственный недостаток заключается в том, что поле ввода останется «маленьким», пока пользователь вводит текст. Или вы можете добавить тайм-аут :) вы также можете проверить такое решение на скрипке выше!


font-sizeне идеальное решение. Неплохо и, конечно, не стоит голосовать против, но попробуйте набрать букву iнесколько раз, и вы увидите очень искаженные результаты в размере. См. Мой ответ, чтобы исправить это.
Пол

см. второй пример в моей скрипке, который не использует размер шрифта и выбирает плавность. Первый был добавлен только для скорости и скорости - при сохранении того, чего хотел спрашивающий. Необходимость создавать div, добавлять к нему текст, вычислять его ширину и т. Д. Каждый раз кажется мне "тяжелой" для чего-то настолько простого.
Пантелис

Я не уверен, почему, но ваш второй пример вообще не меняет размер для меня. Также имейте в виду, что мое решение (которое создает временный div и тому подобное) может работать около 800 раз в секунду в современном браузере в среднем на современном компьютере и, вероятно, не будет намного медленнее, чем 100 раз в секунду на 99,5 % компьютеров, которые все еще используются сегодня)
Пол

2

Я знаю, что это очень старый пост, но мой ответ в любом случае может быть полезен другим, так что приступим. Я обнаружил, что если мое определение стиля CSS для contenteditable div имеет min-height 200 вместо высоты 200, тогда div автоматически масштабируется.


1

Если вы просто заинтересованы в росте, вы можете обновлять widthдо scrollWidth, когда inputизменяется содержимое элемента.

document.querySelectorAll('input[type="text"]').forEach(function(node) {
  node.onchange = node.oninput = function() {
    node.style.width = node.scrollWidth+'px';
  };
});

Но это не приведет к усадке элемента.


1

Какой подход вы используете, конечно, зависит от вашей конечной цели. Если вы хотите отправить результаты с помощью формы, то использование собственных элементов формы означает, что вам не нужно использовать скрипты для отправки. Кроме того, если сценарии отключены, резервное копирование по-прежнему работает без причудливых эффектов роста-сжатия. Если вы хотите получить простой текст из контентного элемента, вы всегда можете использовать скрипты, такие как node.textContent чтобы html, который браузеры вставляют в пользовательский ввод.

В этой версии используются собственные элементы формы с небольшими уточнениями в некоторых из предыдущих сообщений.

Это позволяет также уменьшать размер содержимого.

Используйте это в сочетании с CSS для лучшего контроля.

<html>

<textarea></textarea>
<br>
<input type="text">


<style>

textarea {
  width: 300px;
  min-height: 100px;
}

input {
  min-width: 300px;
}


<script>

document.querySelectorAll('input[type="text"]').forEach(function(node) {
  var minWidth = parseInt(getComputedStyle(node).minWidth) || node.clientWidth;
  node.style.overflowX = 'auto'; // 'hidden'
  node.onchange = node.oninput = function() {
    node.style.width = minWidth + 'px';
    node.style.width = node.scrollWidth + 'px';
  };
});

Вы можете использовать что-то подобное с элементами <textarea>

document.querySelectorAll('textarea').forEach(function(node) {
  var minHeight = parseInt(getComputedStyle(node).minHeight) || node.clientHeight;
  node.style.overflowY = 'auto'; // 'hidden'
  node.onchange = node.oninput = function() {
    node.style.height = minHeight + 'px';
    node.style.height = node.scrollHeight + 'px';
  };
});

Это не мерцает в Chrome, результаты могут отличаться в других браузерах, поэтому проверьте.


0

Вот метод, который у меня сработал. Когда вы вводите текст в поле, он помещает этот текст в скрытый диапазон, затем получает новую ширину и применяет его к полю ввода. Он растет и сжимается вместе с вашим вводом, с защитой от фактического исчезновения ввода, когда вы стираете все вводимые данные. Проверено в Chrome. (РЕДАКТИРОВАТЬ: работает в Safari, Firefox и Edge на момент редактирования)

function travel_keyup(e)
{
    if (e.target.value.length == 0) return;
    var oSpan=document.querySelector('#menu-enter-travel span');
    oSpan.textContent=e.target.value;
    match_span(e.target, oSpan);
}
function travel_keydown(e)
{
    if (e.key.length == 1)
    {
        if (e.target.maxLength == e.target.value.length) return;
        var oSpan=document.querySelector('#menu-enter-travel span');
        oSpan.textContent=e.target.value + '' + e.key;
        match_span(e.target, oSpan);
    }
}
function match_span(oInput, oSpan)
{
    oInput.style.width=oSpan.getBoundingClientRect().width + 'px';
}

window.addEventListener('load', function()
{
    var oInput=document.querySelector('#menu-enter-travel input');
    oInput.addEventListener('keyup', travel_keyup);
    oInput.addEventListener('keydown', travel_keydown);

    match_span(oInput, document.querySelector('#menu-enter-travel span'));
});
#menu-enter-travel input
{
	width: 8px;
}
#menu-enter-travel span
{
	visibility: hidden;
    position: absolute;
    top: 0px;
    left: 0px;
}
<div id="menu-enter-travel">
<input type="text" pattern="^[0-9]{1,4}$" maxlength="4">KM
<span>9</span>
</div>


0

Если вам разрешено использовать измерение ch (моноширинный), это полностью решит то, что я пытался сделать.

onChange(e => {
    e.target.style.width = `${e.target.length}ch`;
})

Это было именно то, что мне нужно, но я не уверен, работает ли это для семейств шрифтов с динамической шириной.


0

Для тех, кто строго ищет решение, которое работает для ввода или текстового поля, это самое простое решение, с которым я столкнулся. Всего несколько строк CSS и одна строка JS.

JavaScript устанавливает атрибут data- * для элемента, равный значению ввода. Входные данные устанавливаются в сетке CSS, где эта сетка является псевдоэлементом, который использует этот атрибут data- * в качестве своего содержимого. Это содержимое растягивает сетку до подходящего размера в зависимости от входного значения.


0

Все, что вам нужно сделать, это получить элемент поля ввода, который вы хотите увеличивать по мере ввода и в CSS, установить ширину ввода на auto и установить min-width, чтобы сказать, 50 пикселей.


Добро пожаловать в Stack Overflow. Прочтите, пожалуйста, как ответить. stackoverflow.com/questions/how-to-answer
Ран Марчиано
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.