Существует ли плагин jQuery autogrow для текстовых полей?

Я нашел различные плагины для автоматического увеличения области текста, но не для ввода текстовых полей. Кто-нибудь знает, существует ли кто-нибудь?

10 ответов

Решение

Вот плагин, который будет делать то, что вы после:

РЕДАКТИРОВАТЬ: я исправил плагин в соответствии с комментарием Матиаса.:)

Посмотреть демо здесь: http://jsfiddle.net/rRHzY

Плагин:

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

У меня есть плагин jQuery на GitHub: https://github.com/MartinF/jQuery.Autosize.Input

Он использует тот же подход, что и ответ Джеймса, но имеет некоторые изменения, упомянутые в комментариях.

Вы можете увидеть живой пример здесь: http://jsfiddle.net/mJMpw/6/

Пример:

<input type="text" value="" placeholder="Autosize" data-autosize-input='{ "space": 40 }' />

input[type="data-autosize-input"] {
  width: 90px;
  min-width: 90px;
  max-width: 300px;
  transition: width 0.25s;    
}

Вы просто используете css для установки min/max-width и используете переход по ширине, если вы хотите получить хороший эффект.

Вы можете указать пробел / расстояние до конца как значение в нотации json для атрибута data-autosize-input элемента input.

Конечно, вы также можете просто инициализировать его с помощью jQuery

$("selector").autosizeInput();

Хороший плагин, спасибо! Я изменил две вещи, которые, казалось, работали лучше в моем проекте.

  1. Я изменил тег TESTER на DIV, чтобы избежать "неожиданного вызова метода или доступа к свойству". в IE8 (даже если ваша демонстрация работает в IE8. Была ли особая причина для использования пользовательского тега HTML?
  2. После оператора bind ближе к концу кода я добавил вызов check(), чтобы изменить размер текстового поля сразу после загрузки страницы, если в текстовом поле уже есть содержимое при запуске.

Надеюсь это поможет.

Просто хотел поделиться небольшим улучшением с замечательным плагином Джеймса. Добавьте этот код в объявление CSS для элемента tester для учета text-indent:

textIndent: 0

Без этого в некоторых ситуациях элемент-тестер может непреднамеренно унаследовать текстовый отступ из другого места, тем самым отбрасывая размер ввода.

Как и JP, я также хотел изменить размер ввода до правильного размера с самого начала, что я сделал немного по-другому, связав "trigger('keyup')" с вызовом метода autoGrowInput, например:

$('#contact_form').autoGrowInput({comfortZone: 7, minWidth: 10, maxWidth: 200}).trigger('keyup');

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

Я создал плагин для ввода текста типа, который воссоздает это поведение. У этого есть некоторые другие уникальные особенности. Вы можете увидеть пример и просмотреть документацию плагина. У @james answer есть проблемы с вставкой большого объема текста во входные данные. Чтобы исправить это, я сделал некоторые изменения в его коде. Вот демо, для этого примера.

(function($){        
    $.fn.autoGrowInput = function(o) {

        o = $.extend({
            maxWidth: 200,
            minWidth: 1,
            comfortZone: 1,
          width: 1
        }, o);

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

            var minWidth = o.minWidth || $(this).width(),
                maxWidth = o.maxWidth,
                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,
                    currentWidth = input.width();

                   if (testerWidth < minWidth) {
                       newWidth = minWidth;
                   } else if (testerWidth > maxWidth) {
                       newWidth = maxWidth;
                   } 

                   input.width(newWidth + o.comfortZone);  
            };

            testSubject.insertAfter(input);

            $(this).bind('input', check);

        });

        return this;

    };

})(jQuery);

Я также заменил

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

в

$(this).bind('keyup blur update', check).bind('keydown', function() {
    setTimeout(check);
});

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

Я создал плагин под названием input-autogrow чтобы решить эту проблему для моих собственных проектов. Этот плагин изначально был основан на ответе Джеймса, но был улучшен во многих отношениях.

https://github.com/westonganger/input-autogrow

input-autogrow это плагин для автостраничных входов Этот плагин отличается от других тем, что чаще всего он предназначен для тегов textarea, а библиотека предназначена для входных тегов. Требуется библиотека DOM, такая как jQuery, Zepto или любая, которая поддерживает плагины $.fn.

Вот несколько примеров использования.

/* Makes elements readonly if they already have the readonly attribute */
$('input.autogrow').inputAutogrow();

/* Manually trigger update */
$('input.autogrow').trigger('autogrow');
/* or */
$('input.autogrow').trigger('change');

/* Custom Options */
$('input.autogrow').inputAutogrow({maxWidth: 500, minWidth: 25, trailingSpace: 10});

/* Remove autogrow from input */
$('input.autogrow').inputAutogrow('destroy');

Потрясающий плагин Джеймс! Благодарю. Я добавил предложение проверки в конце JP, хотя и очень эффективно.

Также я добавил некоторые изменения с моей стороны. Я хотел установить максимальный размер для ввода, если измененная ширина превысила maxWidth, поэтому я добавил:

else if (widthexceeds){
    input.width(o.maxWidth);
}

ниже проверки if для isValidWidthChange где widthexceeds = newWidth > o.maxWidth

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

В приведенном ниже сценарии "#test" является идентификатором текстового поля.

<script language="javascript" type="text/javascript">
$(document).ready(function(){
    $("#test").keyup(function(){
        if($("#test").attr("size") < $("#test").val().length){
            size = $("#test").val().length;
            $("#test").attr("size",size);
        }
    })
});
</script>

Достаточно забавно в переполнении IE: видимый воспринимается очень серьезно. Вы можете достичь этого эффекта, применив overflow: visible к вашим элементам ввода. Не уверен, существуют ли какие-либо похожие хитрости CSS для современных браузеров.

Другие вопросы по тегам