React.js에서textarea에서 Tab 키를 눌렀을 때 공백을 입력하십시오

15229 단어 ReactJavaScript
일반적으로 textarea에 초점을 맞출 때 탭 키를 입력하면 초점이 다음 객체로 이동합니다.
하지만 textarea로 탭을 치면 4개의 공간을 입력하기가 어려워 글을 썼다.

운영 환경


다음 환경에서 실행할 수 있는 내용은 문장입니다.
  • Node.js: 8.9.4
  • React.js: 16.2.0
  • babel-preset-env: 1.6.1
  • blocsers:last2 versions(2018년 1월 14일 현재)
  • 어쨌든 코드

    class SomeTextarea extends React.Component {
    
      constructor(props) {
        super(props);
        this.state = {
          'text': '',
        };
      }
    
      handleChange(e) {
        this.setState({ text: e.target.value });
      }
    
      handleKeyDown(e) {
    
        if (e.key === 'Tab' && e.keyCode !== 229) {
          e.preventDefault();
    
          const textareaElement = e.target;
    
          const currentText = textareaElement.value;
    
          const start = textareaElement.selectionStart;
          const end = textareaElement.selectionEnd;
    
          const spaceCount = 4;
          const substitution = Array(spaceCount + 1).join(' ');
    
          const newText = currentText.substring(0, start) + substitution + currentText.substring(end, currentText.length);
    
          this.setState({
            text: newText,
          }, () => {
            textareaElement.setSelectionRange(start + spaceCount, start + spaceCount);
          });
        }
      }
    
      render() {
        return (
          <textarea
            onChange={this.handleChange.bind(this)}
            onKeyDown={this.handleKeyDown.bind(this)}
          ></textarea>
        );
      }
    }
    

    설명


    Change 활동 및 KeyDown 활동 활용

      handleChange(e) {
        // Changeイベントでは普通に値を更新する
        // この時、Tabキーをタイプした時は何も値が変化しない(そもそも何も入力しないため)
        this.setState({ text: e.target.value });
      }
    
      handleKeyDown(e) {
        // タイプしたキーがTabキーの時 かつ 日本語入力未確定状態でない時に実行する
        if (e.key === 'Tab' && e.keyCode !== 229) {
          ...
        }
      }
    
      render() {
        return (
          <textarea
            onChange={this.handleChange.bind(this)}
            onKeyDown={this.handleKeyDown.bind(this)}
          ></textarea>
        );
      }  
    
    여기에는 onChangeonKeyDown 두 가지 활동이 보충되어 있다.onChange 속성에서 입력한 문자가 일반 업데이트됩니다.
    또한onKeyDown 탭 키가 타자될 때만 특수 처리(이번에는 4개의 공간을 삽입할 수 있음)할 수 있음을 보충해야 한다.
    이때 keyCode 여부229도 판정했는데, 이는 IME가 일본어 입력이 된 상태에서 IME의 변환 후보를 선택할 때 탭키 유형을 사용하지 않고 처리하기 위한 것이다.만약 이렇게 하지 않는다면, 후보 변환을 선택할 때마다 4개의 빈칸을 삽입할 것이다.
    ※ 단, KeyboardEvent.키코드는 deprecated입니다. 때문에 앞으로도 사용할 수 없습니다.
    원래 IME의 입력 문자의 미확정 상태는 Keyboard EventisComposing 속성에서 검출되기 때문에 판정식e.key === 'Tab' && !e.isComposing으로 설정하는 등 비deprecated 방법으로 가능할 것으로 보인다.
    다만, KeyboardEvent.isComposing IE와 사파리는 지원하지 않으며, 이를 사용하기에는 아직 이르기 때문에 다음keyCode 사용법을 소개한다.(이 부분의 좋은 방법을 아는 사람이 있다면 알려주세요.)

    탭 키의 초점 이동 억제

        e.preventDefault();
    
    탭 키를 입력한 경우 이벤트를 취소하지 않으면 포커스가 다음 객체로 이동합니다.
    따라서 KeyboardEventpreventDefault()를 사용하여 그 행위를 억제한다.

    현재 선택 영역 가져오기

          // focusしているtextarea Elementを取得
          const textareaElement = e.target;
    
          // 現在の入力されている文字列
          const currentText = textareaElement.value;
    
          // 現在の選択範囲の先頭側のインデックス
          const start = textareaElement.selectionStart;
          // 過去の選択範囲の末尾側のインデックス
          const end = textareaElement.selectionEnd;
    
    우선 e.target에서 취득<textarea>한 DOM 대상자HTMLTextAreaElement.
    현재 입력한 문자열과 선택한 영역의 첫 번째 색인을 가져옵니다.
  • 범위를 선택하지 않은 경우
  • 범위 선택

  • 공백을 삽입하는 문자열 만들기

          // スペースの数を定義(以下は4スペースの場合)
          const spaceCount = 4;
          // Tabキーを押したときに入力する文字(今回のケースでは '    ' となる)
          const substitution = Array(spaceCount + 1).join(' ');
    
          // 選択されている部分文字列を substitution に置換する(もっとスッキリ書けそう…?)
          const newText = currentText.substring(0, start) + substitution + currentText.substring(end, currentText.length);
    
    네 개의 빈칸을 삽입한 새 문자열을 만들 수 있습니다.substitution는 4개의 공백이고 선택 영역의 인덱스를 사용하여 선택 영역 부분을 substitution로 바꿉니다.

    삽입 공백 후의 문자열을 설정하고 커서를 이동합니다.

          // 置換後の文字列をセットする
          // また、置換後の文字列のセットが反映された後に、カーソルの位置の修正処理を行うようにする
          this.setState({
            text: newText,
          }, () => {
            // 入力中のカーソルを置き換えたスペースの末尾に移動させる
            textareaElement.setSelectionRange(start + spaceCount, start + spaceCount);
          });
    
    textarea의 입력 문자열을 업데이트합니다.
    업데이트가 완료되면 입력 커서의 위치를 삽입된 4개의 공백 끝으로 이동합니다.코드는 커서의 현재 위치 + 공백 4자의 위치입니다.
    setState의callback을 사용하지 않으면state가 업데이트되기 전에 커서의 이동 처리를 하고 커서가 이상한 곳으로 이동합니다. 주의하십시오.

    최후


    위에서 설명한 대로 Tab 키를 누를 때 공백을 입력할 수 있습니다.하지만 주변 환경에 IE가 없기 때문에 IE로 검증할 수 없으니 안 되면 알려주세요.
    겸사겸사 말씀드리겠습니다.js를 사용하면 페이스북Draft.js을 사용하면 이 행동을 실현할 수 있다.
    https://github.com/facebook/draft-js/issues/121
    (버블의 JS 파일 크기를 확대하고 싶지 않아 이번에는 사용하지 않았다.)

    좋은 웹페이지 즐겨찾기