Создание текстовой области с автоматическим изменением размера - PullRequest
309 голосов
/ 18 января 2009

Был другой поток об этом , который я пробовал. Но есть одна проблема: textarea не уменьшается при удалении контента. Я не могу найти способ уменьшить его до правильного размера - значение clientHeight возвращается как полный размер textarea, а не его содержимое.

Код с этой страницы ниже:

function FitToContent(id, maxHeight)
{
   var text = id && id.style ? id : document.getElementById(id);
   if ( !text )
      return;

   var adjustedHeight = text.clientHeight;
   if ( !maxHeight || maxHeight > adjustedHeight )
   {
      adjustedHeight = Math.max(text.scrollHeight, adjustedHeight);
      if ( maxHeight )
         adjustedHeight = Math.min(maxHeight, adjustedHeight);
      if ( adjustedHeight > text.clientHeight )
         text.style.height = adjustedHeight + "px";
   }
}

window.onload = function() {
    document.getElementById("ta").onkeyup = function() {
      FitToContent( this, 500 )
    };
}

Ответы [ 38 ]

1 голос
/ 01 августа 2014

Еще более простой и понятный подход:

// adjust height of textarea.auto-height
$(document).on( 'keyup', 'textarea.auto-height', function (e){
    $(this).css('height', 'auto' ); // you can have this here or declared in CSS instead
    $(this).height( this.scrollHeight );
}).keyup();

// и CSS

textarea.auto-height {
    resize: vertical;
    max-height: 600px; /* set as you need it */
    height: auto;      /* can be set here of in JS */
    overflow-y: auto;
    word-wrap:break-word
}

Все, что нужно, это добавить класс .auto-height к любому textarea, на который вы хотите нацелиться.

Проверено в FF, Chrome и Safari. Дайте мне знать, если это не сработает для вас, по любой причине. Но это самый чистый и простой способ, который я нашел, чтобы это работало. И это прекрасно работает! : D

1 голос
/ 30 сентября 2016

Просто используйте с некоторыми стилями, такими как:

    pre {
        font-family: Arial, Helvetica, sans-serif;
        white-space: pre-wrap;
        word-wrap: break-word;
        font-size: 12px;
        line-height: 16px;
    }
1 голос
/ 12 сентября 2016

Этот код работает для вставки и выберите также удалить.

onKeyPressTextMessage = function(){
			var textArea = event.currentTarget;
    	textArea.style.height = 'auto';
    	textArea.style.height = textArea.scrollHeight + 'px';
};
<textarea onkeyup="onKeyPressTextMessage(event)" name="welcomeContentTmpl" id="welcomeContent" onblur="onblurWelcomeTitle(event)" rows="2" cols="40" maxlength="320"></textarea>

Вот JSFiddle

1 голос
/ 15 апреля 2019

Те, кто хочет добиться того же в новых версиях Angular.

Grab textArea elementRef.

@ViewChild('textArea', { read: ElementRef }) textArea: ElementRef;

public autoShrinkGrow() {
    textArea.style.overflow = 'hidden';
    textArea.style.height = '0px';
    textArea.style.height = textArea.scrollHeight + 'px';
}

<textarea (keyup)="autoGrow()" #textArea></textarea>

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

  public autoGrowShrinkToCertainHeight() {
    const textArea = this.textArea.nativeElement;
    if (textArea.scrollHeight > 77) {
      textArea.style.overflow = 'auto';
      return;
    }
    else {
      textArea.style.overflow = 'hidden';
      textArea.style.height = '0px';
      textArea.style.height = textArea.scrollHeight + 'px';
    }
  }
0 голосов
/ 17 января 2019

Лучший способ, который я нашел:

$("textarea.auto-grow").each( function(){
    $(this).keyup(function(){
        $(this).height( $(this)[0].scrollHeight - Number( $(this).css("font-size").replace("px", "") ) );
    });
});

У других способов есть ошибка размера шрифта.

Вот почему это лучшее.

0 голосов
/ 07 сентября 2009

Я протестировал скрипт в обычных браузерах, но он не удался в Chrome и Safari. Это из-за постоянно обновляемой переменной scrollHeight.

Я применил скрипт DisgruntledGoat с использованием jQuery и добавил исправление chrome

function fitToContent(/* JQuery */text, /* Number */maxHeight) {
    var adjustedHeight = text.height();
    var relative_error = parseInt(text.attr('relative_error'));
    if (!maxHeight || maxHeight > adjustedHeight) {
        adjustedHeight = Math.max(text[0].scrollHeight, adjustedHeight);
        if (maxHeight)
            adjustedHeight = Math.min(maxHeight, adjustedHeight);
        if ((adjustedHeight - relative_error) > text.height()) {
            text.css('height', (adjustedHeight - relative_error) + "px");
            // chrome fix
            if (text[0].scrollHeight != adjustedHeight) {
                var relative = text[0].scrollHeight - adjustedHeight;
                if (relative_error != relative) {
                    text.attr('relative_error', relative + relative_error);
                }
            }
        }
    }
}

function autoResizeText(/* Number */maxHeight) {
    var resize = function() {
        fitToContent($(this), maxHeight);
    };
    $("textarea").attr('relative_error', 0);
    $("textarea").each(resize);
    $("textarea").keyup(resize).keydown(resize);
}
0 голосов
/ 19 июня 2018

MakeTextAreaResisable, использующий qQuery

function MakeTextAreaResisable(id) {
    var o = $(id);
    o.css("overflow-y", "hidden");

    function ResizeTextArea() {
        o.height('auto');
        o.height(o[0].scrollHeight);
    }

    o.on('change', function (e) {
        ResizeTextArea();
    });

    o.on('cut paste drop keydown', function (e) {
        window.setTimeout(ResizeTextArea, 0);
    });

    o.focus();
    o.select();
    ResizeTextArea();
}
0 голосов
/ 23 мая 2018

Ни один из ответов не работает. Но этот работает для меня: https://coderwall.com/p/imkqoq/resize-textarea-to-fit-content

$('#content').on( 'change keyup keydown paste cut', 'textarea', function (){
    $(this).height(0).height(this.scrollHeight);
}).find( 'textarea' ).change();
0 голосов
/ 02 октября 2010

Если scrollHeight можно доверять, то:

textarea.onkeyup=function() {
  this.style.height='';
  this.rows=this.value.split('\n').length;
  this.style.height=this.scrollHeight+'px';
}
0 голосов
/ 18 ноября 2017

Собственное решение Javascript без мерцания в Firefox и быстрее, чем метод withclientHeight ...

1) Добавьте селектор div.textarea ко всем селекторам, содержащим textarea. Не забудьте добавить box-sizing: border-box;

2) Включить этот скрипт:

function resizeAll()
{
   var textarea=document.querySelectorAll('textarea');
   for(var i=textarea.length-1; i>=0; i--)
      resize(textarea[i]);
}

function resize(textarea)
{
   var div = document.createElement("div");
   div.setAttribute("class","textarea");
   div.innerText=textarea.value+"\r\n";
   div.setAttribute("style","width:"+textarea.offsetWidth+'px;display:block;height:auto;left:0px;top:0px;position:fixed;z-index:-200;visibility:hidden;word-wrap:break-word;overflow:hidden;');
   textarea.form.appendChild(div);
   var h=div.offsetHeight;
   div.parentNode.removeChild(div);
   textarea.style.height=h+'px';
}

function resizeOnInput(e)
{
   var textarea=document.querySelectorAll('textarea');
   for(var i=textarea.length-1; i>=0; i--)
      textarea[i].addEventListener("input",function(e){resize(e.target); return false;},false);
}

window.addEventListener("resize",function(){resizeAll();}, false);
window.addEventListener("load",function(){resizeAll();}, false);
resizeOnInput();

Протестировано на IE11, Firefox и Chrome.

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

...