Есть ли способ заставить текстовую область растягиваться, чтобы соответствовать ее содержимому, без использования PHP или JavaScript?

Я заполняю текстовое поле содержимым, которое пользователь может редактировать.

Можно ли растянуть его, чтобы он соответствовал контенту с помощью CSS (например, overflow:show за див)

15 ответов

Решение

На самом деле, нет. Обычно это делается с помощью JavaScript.

есть хорошее обсуждение способов сделать это здесь...

Авторазмер текстовой области с использованием Prototype

Только одна строка

<textarea name="text" oninput='this.style.height = "";this.style.height = this.scrollHeight + "px"'></textarea>

В качестве альтернативы вы можете использовать элемент, который будет соответствовать тексту внутри.

      <div contenteditable>Try typing and returning.</div>

Обратите внимание, что это значение невозможно отправить в форме без использования JavaScript. Также contenteditable возможно, будет генерировать HTML-контент и разрешить стили, поэтому его, возможно, потребуется отфильтровать при отправке формы.

Не на 100% связано с вопросом, так как это только для Angular .

Существует пакет npm, связанный с Angular, который называется @angular/cdk (если используется Angular Material Design). В этот пакет включено свойство, которое можно связать с текстовой областью cdkTextareaAutosize. Это автоматически устанавливает текстовую область в 1 строку и растягивает текстовую область, чтобы соответствовать содержимому соответственно. Если вы используете эту библиотеку, что-то вроде этого должно работать.

          <textarea 
      maxLength="200"
      cdkTextareaAutosize
      type="text">
    </textarea>

Вот функция, которая работает с jQuery (только для высоты, а не для ширины):

function setHeight(jq_in){
    jq_in.each(function(index, elem){
        // This line will work with pure Javascript (taken from NicB's answer):
        elem.style.height = elem.scrollHeight+'px'; 
    });
}
setHeight($('<put selector here>'));

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

Это очень простое решение, но оно работает для меня:

<!--TEXT-AREA-->
<textarea id="textBox1" name="content" TextMode="MultiLine" onkeyup="setHeight('textBox1');" onkeydown="setHeight('textBox1');">Hello World</textarea>

<!--JAVASCRIPT-->
<script type="text/javascript">
function setHeight(fieldId){
    document.getElementById(fieldId).style.height = document.getElementById(fieldId).scrollHeight+'px';
}
setHeight('textBox1');
</script>

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

      var $textareas = $('textarea');
$textareas.each(function() { // to avoid the shrinking
    this.style.minHeight = this.offsetHeight + 'px';
});

$textareas.on('input', function() {
    this.style.height = '';
    this.style.height = this.scrollHeight + 'px';
});

Еще одно простое решение для управления динамическим текстовым полем.

<!--JAVASCRIPT-->
<script type="text/javascript">
$('textarea').on('input', function () {
            this.style.height = "";
            this.style.height = this.scrollHeight + "px";
 });
</script>

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

Этот фрагмент скрипта будет перебирать ВСЕ текстовые области на вашей странице и следить за тем, чтобы они изменяли размер как при загрузке, так и при изменении.

      <script>
  document.querySelectorAll("textarea").forEach(element => {
    function autoResize(el) {
      el.style.height = el.scrollHeight + 'px';
    }
    autoResize(element);
    element.addEventListener('input', () => autoResize(element));
  });
</script>

Только Vanilla JS, никаких библиотек не требуется.

Не совсем, но вы всегда можете использовать:

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

который в некоторых случаях работает как отличная замена<textarea>.


Рабочий пример:


Дальнейшее чтение:

Надежный, многоразовый, более полный и отзывчивый ответ (следит за изменением размеров окна). Вы можете поместить код в модуль JavaScript, см. комментарии ниже о том, как это работает:

      // File: ui.mjs

/* Auto resize a <textarea>'s height to fit its content.
 * Use the HTML attribute `rows` to set the min height of the element, e.g. rows="2"
 */
function runAutoHeight(el) {
    el.style.height = 'auto';
    const computedStyle = getComputedStyle(el)
    const borderTop = parseFloat(computedStyle.getPropertyValue("border-top-width").replace('px',''));
    const borderBottom = parseFloat(computedStyle.getPropertyValue("border-bottom-width").replace('px',''));
    el.style.height = String(el.scrollHeight + borderTop + borderBottom) + 'px';
}

/* Sets up autoHeight for the given element for the following 2 situations:
 *  1. When the user types in input
 *  2. When the element is resized (e.g. window is resized)
 *
 * It also adds a function to the element called 'autoHeight', which can be manually called.
 * This is useful when setting values to a <textarea> via JS, and hence the `input` event
 * handler will not be run, e.g.:
 *      import * as ui from '/static/path/to/your/ui.mjs';
 *      ui.setupAutoHeight(el)
 *      el.value = "Manually setting value won't fire change event"
 *      el.autoHeight()
 */
export function setupAutoHeight(el) {
    el.autoHeight = () => runAutoHeight(el);
    el.style.resize = "none";
    // Watch for window resizes
    const observer = new ResizeObserver(el.autoHeight);
    observer.observe(el);
    // Watch for changes in text input
    el.addEventListener('input', el.autoHeight)
}
          <script>
        document.querySelectorAll("textarea").forEach(element => {
            function autoResize(el) {
                if (el.scrollHeight > el.offsetHeight) {
                    el.style.height = el.scrollHeight + 'px';
                }
            }
            autoResize(element);
            element.addEventListener('input', () => autoResize(element));
        });
    </script>

Решение проблемы сжатия при вводе ввода, которое я испытал в фантастической функции dezman (см. dezman выше). Я добавил сравнение со свойством, на которое FTW ссылается в своем посте чуть выше имени .offsetHeight Дезмана.

В функции dezman, когда ScrollHeight меньше, чем offsetHeight— например, 1 строка текста в текстовой области размером 5 строк — тогда корректировка, внесенная в el.style.height после каждого нажатия клавиши, непреднамеренно уменьшала размер offsetheight. Смещение продолжало уменьшаться в сторону значения ScrollHeight, что создавало впечатление сжимающейся текстовой области.

Запуск корректировки style.height только тогда, когда ввод текста приводит к увеличению ScrollHeight за пределами .offsetheight, предотвращает сжатие offsetHeight при каждом нажатии клавиши.

СПАСИБО, Дезман и FTW выше...

Решение для React

Я использовал длину отображаемого текста и разделил это число на 30 (я скорректировал это число до тех пор, пока оно не стало правильным в моем приложении).

      {array.map((text) => (
    <textarea                
     rows={text.length / 30}
     value={text}
    ></textarea>
 )}

Если вы используете ионную систему, просто добавьте этот атрибут в текстовую область:

       autoGrow="true" 

См. этот ответ:ion-textarea динамически изменяет размер высоты в Ionic 5

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