JavaScript

textareaを中身に応じて自動リサイズする

textareaを内容に応じてリサイズするclassを作りました。How to useに書いてある様に書けば動くと思いますが、もし動作しなかった場合はコメントにて教えてもらえると助かります :bow:

/*
 * How to use
 *
 * import ResizeTextarea from './path/to/ResizeTextarea';
 * let textarea = document.querySelector('#textarea');
 * const resizeTextarea = new ResizeTextarea(textarea);
 * textarea.addEventListener('input', () => {
 *   resizeTextarea.resize();
 * });
 */

export default class ResizeTextarea {
  constructor(textarea) {
    this.textarea = textarea;
    this.style = window.getComputedStyle(textarea, null)
  }

  resize() {
    if (this.scrollHeight > this.offsetHeight) {
      this.height = this.scrollHeight;
    } else {
      while(true) {
        this.height = this.height - this.lineHeight;
        if (this.scrollHeight >= this.offsetHeight) {
          this.height = this.scrollHeight;
          break;
        }
      }
    }
  }

  // get height of textarea from inline style attribute or css
  // return Number
  get height() {
    let heightCss = this.textarea.style.height || this.style.getPropertyValue('height');
    return Number(heightCss.slice(0, -2)) || 0;
  }

  // get line-height of textarea from inline style attribute or css
  // return Number
  get lineHeight() {
    let lineHeightCss = this.textarea.style.lineHeight || this.style.getPropertyValue('line-height');
    return Number(lineHeightCss.slice(0, -2)) || 0;
  }

  // return Number
  get scrollHeight() {
    return this.textarea.scrollHeight;
  }

  // return Number
  get offsetHeight() {
    return this.textarea.offsetHeight;
  }

  // param Number
  set height(height) {
    if (typeof(height) !== 'number') console.error('expect: ResizeTextarea get heightの引数は数値です。got: ', typeof(height));
    this.textarea.style.height = height + 'px';
  }
}