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


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

width: 50px;

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

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

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

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

10 60

10 ответов:

вот пример только с CSS и Контент Редактируемым:

пример jsFiddle

CSS

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

HTML

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

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

(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

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

семантически (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/

от: есть ли плагин 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);

несколько вещей приходят на ум:

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

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

* это не просто измерить текст в javascript. Проверьте этот вопрос ради какой-то идеи.

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

EDIT: пересмотренный пример (добавлено одно новое решение) 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;
}

EDIT: другое решение состоит в том, чтобы пользователь набрал то, что он хочет, и на размытие (фокус), возьмите строку (в том же размере шрифта) поместите ее в div - подсчитайте ширину div - а затем с хорошей анимацией с прохладной эффект смягчения обновите ширину входных полей. Единственным недостатком является то, что поле ввода будет оставаться "маленьким", когда пользователь вводит. Или вы можете добавить тайм-аут :) вы можете проверить такое решение на скрипке выше тоже!

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

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

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

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

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

но это не будет сокращаться элемент.

какой подход вы используете, конечно, зависит от того, какова ваша конечная цель. Если вы хотите отправить результаты с помощью формы, то использование собственных элементов формы означает, что вам не нужно использовать сценарии для отправки. Кроме того, если сценарий отключен, то резервный вариант по-прежнему работает без причудливых эффектов роста и сжатия. Если вы хотите получить простой текст из contenteditable элемент, вы всегда можете использовать скрипты, как узел.текстового содержимого чтобы удалить 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';
  };
});

вы можете использовать что-то подобное с

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, результаты могут отличаться в других браузерах, так что тест.