Как я могу автоматически подгонять / изменять размер элемента html5 textarea, чтобы соответствовать исходному содержимому? - PullRequest
5 голосов
/ 26 марта 2020

Цель:

Я ищу способ в javaScript / jQuery изменить размер текстовой области таким образом, чтобы он изначально отображал все свое текстовое содержимое, скрыв вертикальную полосу прокрутки, и покажите маркер изменения размера.

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

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

Повторное нажатие кнопки вызывает текстовая область расширяется, так что ни одна из текущих строк не переносится.

Повторное нажатие кнопки теперь приводит к росту текстовой области, так что вертикальная полоса прокрутки больше не отображается.

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

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

const text = 'This is a line of text';

var   $textarea = $( '#example' );
var   i         = 0;

$textarea.val( $textarea.val() + text );
for( var l = i + 5 ; i < l; ++i )
  $textarea.val( $textarea.val() + "\r\n" + text + '(' + i + ')' );

function doIt( This ) {
  if( This.innerText !== 'Click Me Again' ) {

    for( var l = i + 5 ; i < l; ++i )
      $textarea.val( $textarea.val() + "\r\n" + text + '(' + i + ')' );

    if( This.innerText === 'Click Me' ) {

      This.innerText = 'Click Me Again';
      $( 'p' ).text( 'to make the textarea\s width wider.' );

    }
    else {

      $textarea.css( 'height', 'auto' );  // As per Mr Khan's sugestion.

      $textarea.css( 'height', $textarea[ 0 ].scrollHeight + 'px' );

      $( 'p' ).html( '<b>Why is there space below the last line of text?</b>' );

    }

  }
  else {

    This.innerText = 'Click Me Some More';
    $textarea.css( 'width', ( $textarea.width() + 36 ) + 'px' );
    $( 'p' ).text( 'to make the textarea\'s height taller and add more text.' );

  }
}
#example { width: 185px; height: 100px; overflow: auto; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
    <meta http-equiv="Content-type" content="text/html; charset=utf-8">
    <title>jQuery getScrollBarWidth example</title>
  </head>
  <body>
    <h1>Snippet Example</h1>
    <button onclick="doIt( this );">Click Me</button><br />
    <p>to add more text to the textarea.</p>
    <textarea id="example"></textarea>
  </body>
</html>

Обновление codePen работает до 1000 строк, когда используется опция Rows. После 999 строк корректировка атрибута строки текстовой области больше не работает, поскольку каждая строка переносится на две строки, поэтому после 999 строк, вероятно, потребуется добавить 2 к атрибуту строк (не проверено), чтобы предотвратить показ вертикальной полосы прокрутки, но вверх 999 строк, скорее всего, достаточно хорошо почти для любой ситуации. Спасибо.

1 Ответ

3 голосов
/ 26 марта 2020

Просто установите высоту в автоматический режим перед установкой scrollheight, и вам подойдет go

$textarea.css( 'height', 'auto' );
$textarea.css( 'height', $textarea[ 0 ].scrollHeight + 'px' );

Пример работы:

const text = 'This is a line of text';

var   $textarea = $( '#example' );
var   i         = 0;

$textarea.val( $textarea.val() + text );
for( var l = i + 5 ; i < l; ++i )
  $textarea.val( $textarea.val() + "\r\n" + text + '(' + i + ')' );

$textarea.css( 'height', 'auto' );  //==========> Add this here
$textarea.css( 'height', $textarea[ 0 ].scrollHeight + 'px' ); //==========> Add this here

function doIt( This ) {
  if( This.innerText !== 'Click Me Again' ) {

    for( var l = i + 5 ; i < l; ++i )
      $textarea.val( $textarea.val() + "\r\n" + text + '(' + i + ')' );

    if( This.innerText === 'Click Me' ) {

      This.innerText = 'Click Me Again';
      $( 'p' ).text( 'to make the textarea\s width wider.' );

    }
    else {

      $textarea.css( 'height', 'auto' );  // As per Mr Khan's sugestion.

      $textarea.css( 'height', $textarea[ 0 ].scrollHeight + 'px' );

      $( 'p' ).html( '<b>Why is there space below the last line of text?</b>' );

    }

  }
  else {

    This.innerText = 'Click Me Some More';
    $textarea.css( 'width', ( $textarea.width() + 36 ) + 'px' );
    $( 'p' ).text( 'to make the textarea\'s height taller and add more text.' );

  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button onclick="doIt( this );">Click Me</button><br />
    <p>to add more text to the textarea.</p>
    <textarea id="example"></textarea>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...