[javascript] 자동 크기 조정 기능이있는 텍스트 영역 만들기

내가 시도한 이것대한 또 다른 스레드 가있었습니다 . 그러나 한 가지 문제 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 )
    };
}



답변

이것은 나를 위해 작동합니다 (Firefox 3.6 / 4.0 및 Chrome 10/11).

var observe;
if (window.attachEvent) {
    observe = function (element, event, handler) {
        element.attachEvent('on'+event, handler);
    };
}
else {
    observe = function (element, event, handler) {
        element.addEventListener(event, handler, false);
    };
}
function init () {
    var text = document.getElementById('text');
    function resize () {
        text.style.height = 'auto';
        text.style.height = text.scrollHeight+'px';
    }
    /* 0-timeout to get the already changed text */
    function delayedResize () {
        window.setTimeout(resize, 0);
    }
    observe(text, 'change',  resize);
    observe(text, 'cut',     delayedResize);
    observe(text, 'paste',   delayedResize);
    observe(text, 'drop',    delayedResize);
    observe(text, 'keydown', delayedResize);

    text.focus();
    text.select();
    resize();
}
textarea {
    border: 0 none white;
    overflow: hidden;
    padding: 0;
    outline: none;
    background-color: #D0D0D0;
}
<body onload="init();">
<textarea rows="1" style="height:1em;" id="text"></textarea>
</body>

jsfiddle에서 시도하고 싶다면
한 줄로 시작하여 필요한 양만 자랍니다. 하나는 괜찮지 textareatextarea큰 텍스트 문서에 일반적으로 줄이있는 것만 큼 많은 것들이 많은 것을 쓰고 싶었습니다 . 이 경우 정말 느립니다. (Firefox에서는 엄청나게 느립니다.) 따라서 순수한 CSS를 사용하는 접근법을 정말로 원합니다. 이것은 가능 contenteditable하지만 일반 텍스트 전용 이길 원합니다.


답변

완벽한 아직 간단한 솔루션

2020-05-14
업데이트 (휴대 전화 및 태블릿에 대한 개선 된 브라우저 지원)

다음 코드가 작동합니다 :

  • 키 입력시.
  • 붙여 넣은 텍스트로 (오른쪽 클릭 및 Ctrl + V).
  • 잘린 텍스트 사용 (오른쪽 클릭 및 Ctrl + x).
  • 미리로드 된 텍스트
  • 모든 텍스트 영역 (여러 줄 텍스트 상자)의 사이트 전체
  • 파이어 폭스 (v31-67 테스트).
  • 함께 크롬 (v37-74 테스트).
  • IE (V9-V11 시험).
  • 엣지 (V14-V18 시험).
  • IOS Safari 와 함께 .
  • 안드로이드 브라우저 .
  • 자바 스크립트와 엄격 모드 .
  • W3C 인증 됨.
  • 그리고 능률적이고 효율적입니다.

옵션 1 (jQuery 사용)

이 옵션은 필요 jQuery를 하고 테스트를 거쳤으며들과 협력 1.7.23.3.1

간단합니다 (이 jquery 코드를 마스터 스크립트 파일에 추가하고 잊어 버리십시오).

$('textarea').each(function () {
  this.setAttribute('style', 'height:' + (this.scrollHeight) + 'px;overflow-y:hidden;');
}).on('input', function () {
  this.style.height = 'auto';
  this.style.height = (this.scrollHeight) + 'px';
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<textarea placeholder="Type, paste, cut text here...">PRELOADED TEXT.
This javascript should now add better support for IOS browsers and Android browsers.</textarea>
<textarea placeholder="Type, paste, cut text here..."></textarea>

Test on jsfiddle


옵션 2 (Pure JavaScript)

간단 함 (이 JavaScript를 마스터 스크립트 파일에 추가하고 잊어 버리십시오.)

const tx = document.getElementsByTagName('textarea');
for (let i = 0; i < tx.length; i++) {
  tx[i].setAttribute('style', 'height:' + (tx[i].scrollHeight) + 'px;overflow-y:hidden;');
  tx[i].addEventListener("input", OnInput, false);
}

function OnInput() {
  this.style.height = 'auto';
  this.style.height = (this.scrollHeight) + 'px';
}
<textarea placeholder="Type, paste, cut text here...">PRELOADED TEXT. This JavaScript should now add better support for IOS browsers and Android browsers.</textarea>
<textarea placeholder="Type, paste, cut text here..."></textarea>

Test on jsfiddle


옵션 3 (jQuery 확장)

자동 크기 조정하려는 텍스트 영역에 추가 체인을 적용하려는 경우 유용합니다.

jQuery.fn.extend({
  autoHeight: function () {
    function autoHeight_(element) {
      return jQuery(element)
        .css({ 'height': 'auto', 'overflow-y': 'hidden' })
        .height(element.scrollHeight);
    }
    return this.each(function() {
      autoHeight_(this).on('input', function() {
        autoHeight_(this);
      });
    });
  }
});

호출 $('textarea').autoHeight()


자바 스크립트를 통한 텍스트 업데이트

JavaScript를 통해 텍스트를 텍스트 영역에 삽입 할 때 옵션 1에서 함수를 호출하려면 다음 코드를 추가하십시오.

$('textarea').trigger('input');

사전 설정 텍스트 높이

텍스트 영역의 초기 높이를 수정하려면 추가 조건을 추가해야합니다.

const txHeight = 16;
const tx = document.getElementsByTagName("textarea");
for (let i = 0; i < tx.length; i++) {
  if (tx[i].value == '') {
    tx[i].setAttribute("style", "height:" + txHeight + "px;overflow-y:hidden;");
  } else {
    tx[i].setAttribute("style", "height:" + (tx[i].scrollHeight) + "px;overflow-y:hidden;");
  }
  tx[i].addEventListener("input", OnInput, false);
}

function OnInput(e) {
  this.style.height = "auto";
  this.style.height = (this.scrollHeight) + "px";
}
<textarea placeholder="Type, paste, cut text here...">PRELOADED TEXT. This JavaScript should now add better support for IOS browsers and Android browsers.</textarea>
<textarea placeholder="Type, paste, cut text here..."></textarea>


답변

jQuery 솔루션은 요구 사항에 맞게 CSS를 조정합니다

CSS …

div#container textarea {
    min-width: 270px;
    width: 270px;
    height: 22px;
    line-height: 24px;
    min-height: 22px;
    overflow-y: hidden; /* fixes scrollbar flash - kudos to @brettjonesdev */
    padding-top: 1.1em; /* fixes text jump on Enter keypress */
}

자바 스크립트 …

// auto adjust the height of
$('#container').delegate( 'textarea', 'keydown', function (){
    $(this).height( 0 );
    $(this).height( this.scrollHeight );
});
$('#container').find( 'textarea' ).keydown();

또는 jQuery 1.7 이상에 대한 대안 …

// auto adjust the height of
$('#container').on( 'keyup', 'textarea', function (){
    $(this).height( 0 );
    $(this).height( this.scrollHeight );
});
$('#container').find( 'textarea' ).keyup();

나는 당신의 실험의 시작점으로 절대 최소 스타일을 가진 바이올린을 만들었습니다 …
http://jsfiddle.net/53eAy/951/


답변

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Textarea autoresize</title>
    <style>
    textarea {
        overflow: hidden;
    }
    </style>
    <script>
    function resizeTextarea(ev) {
        this.style.height = '24px';
        this.style.height = this.scrollHeight + 12 + 'px';
    }

    var te = document.querySelector('textarea');
    te.addEventListener('input', resizeTextarea);
    </script>
</head>
<body>
    <textarea></textarea>
</body>
</html>

Firefox 14 및 Chromium 18에서 테스트되었습니다. 숫자 24와 12는 임의적이며 테스트에 가장 적합한 것이 있는지 테스트하십시오.

style 및 script 태그를 사용하지 않고도 할 수 있지만 약간 난해한 imho가됩니다 (이것은 구식 HTML + JS이며 권장되지 않습니다).

<textarea style="overflow: hidden" onkeyup="this.style.height='24px'; this.style.height = this.scrollHeight + 12 + 'px';"></textarea>

편집 : 현대화 된 코드. onkeyup 속성이 addEventListener로 변경되었습니다.
편집 : 키 다운이 키 업보다 낫습니다.
편집 : 편집을 사용하기 전에 함수를 선언
하십시오 : 입력이 키 다운보다 낫습니다 (thnx @ WASD42 & @ MA-Maddin)

jsfiddle


답변

나를위한 가장 좋은 해결책 (작동하고 짧음)은 다음과 같습니다.

    $(document).on('input', 'textarea', function () {
        $(this).outerHeight(38).outerHeight(this.scrollHeight); // 38 or '1em' -min-height
    }); 

붙여 넣기 (마우스 포함)로 깜박임없이 잘라내어 들어가고 들어가며 올바른 크기로 줄어드는 매력처럼 작동합니다.

jsFiddle을 살펴보십시오 .


답변

현재 clientHeight 및 내용 scrollHeight의 높은 값을 사용하고 있습니다. 내용을 제거하여 scrollHeight를 더 작게 만들면 이전에 style.height로 설정 한 clientHeight가 열린 상태이므로 계산 된 영역을 더 작게 만들 수 없습니다. 대신 textarea.rows에서 max ()의 scrollHeight와 최소 높이 값을 미리 정의하거나 계산할 수 있습니다.

일반적으로 폼 컨트롤에서 scrollHeight에 의존해서는 안됩니다. scrollHeight는 다른 IE 확장보다 널리 지원되지 않는 것 외에도 HTML / CSS는 양식 컨트롤이 내부적으로 구현되는 방식에 대해 아무 것도 말하지 않으며 scrollHeight가 의미있는 것이라고 보장하지 않습니다. (전통적으로 일부 브라우저는 작업에 OS 위젯을 사용하여 내부에서 CSS와 DOM 상호 작용을 불가능하게했습니다.) 최소한 효과를 활성화하기 전에 scrollHeight / clientHeight가 있는지 확인하십시오.

더 광범위하게 작동하는 것이 중요한 경우 문제를 피하는 또 다른 가능한 방법은 텍스트 영역과 같은 너비로 크기가 지정된 숨겨진 div를 사용하고 동일한 글꼴로 설정하는 것일 수 있습니다. 키업시 텍스트 영역에서 숨겨진 div의 텍스트 노드로 텍스트를 복사합니다 ( ‘\ n’을 줄 바꿈으로 바꾸고 innerHTML을 사용하는 경우 ‘<‘/ ‘&’을 올바르게 이스케이프해야 함). 그런 다음 div의 offsetHeight를 측정하면 필요한 높이를 얻을 수 있습니다.


답변

IE8을 지원할 필요가없는 경우 다음 input이벤트를 사용할 수 있습니다 .

var resizingTextareas = [].slice.call(document.querySelectorAll('textarea[autoresize]'));

resizingTextareas.forEach(function(textarea) {
  textarea.addEventListener('input', autoresize, false);
});

function autoresize() {
  this.style.height = 'auto';
  this.style.height = this.scrollHeight+'px';
  this.scrollTop = this.scrollHeight;
  window.scrollTo(window.scrollLeft,(this.scrollTop+this.scrollHeight));
}

이제 CSS 만 추가하면됩니다.

textarea[autoresize] {
  display: block;
  overflow: hidden;
  resize: none;
}

용법:

<textarea autoresize>Type here and Ill resize.</textarea>

내 블로그 게시물에서 어떻게 작동하는지 더 자세히 읽을 수 있습니다 .