DOM

html

【JavaScript】textarea内を行番号指定で移動する方法

更新日:2023/04/05

Webページのtextarea要素に文章が入力されているとき、JavaScriptを使って行番号でカーソルを移動させる方法をお伝えします。

 

完成デモ

今回は次のような、textarea内を行番号指定で移動するフォームを作成します。

実際に動作するので、試してみてください。

行番号:

なお現行(2023/4月時点)のChromeとFirefoxおよびSafari(iPad)で動作確認しています。
ブラウザによっては動作しない可能性があります。

 

textarea内を行番号指定で移動する関数

まずは、textarea内を行番号指定で移動する関数のコードから紹介します。

textarea内を行番号指定で移動する関数

const textareaMoveRow = (textarea,rowNumber)=>{
    rowNumber = Number(rowNumber); // 数値変換
    if( isNaN(rowNumber) ) return -1; // 数値ではない
        // 先頭行が指定された
    if( rowNumber <= 0 ) return textareaMoveRow.moveCharPos(rowNumber,0);

        // 指定行の文字位置を調べる
    const text = textarea.value;
    const regx = /\r\n|\n|\r/g;
    let result;
    let count=0;
    while( (result  = regx.exec( text )) !== null ){
        if( ++count === lineNumber ) // 指定行に到達?
            return textareaMoveRow.moveCharPos(textarea,result.index+1);
    }
        // 指定された行番号は範囲外
    return textareaMoveRow.moveCharPos(textarea,text.length);
};
  // textareaの指定文字位置に移動するメソッド
textareaMoveRow.moveCharPos = (textarea,charPos)=>{
    textarea.focus();
    textarea.setSelectionRange(charPos,charPos);
    return charPos;
};

textareaMoveRow()は、第一引数にtextarea要素を、第二引数に0から始まる行番号を指定します。

デモのhtmlは、次のようになっています。

デモのhtml

<p class="spb"><button id="samplebutton">サンプル取得</button></p>
<textarea id="textarea" style="width:100%;height:300px"></textarea>
行番号:<input id="input">
<button id="button">移動</button>

次のコードは、ボタン等を制御するJavaScriptです。

デモのスクリプト

document.addEventListener("DOMContentLoaded",()=>{
    const [input,textarea,button,demosample,samplebutton] =
             ["input","textarea","button","demosample","samplebutton"].map(e=>document.getElementById(e));

    button.addEventListener("click",()=>{
        textareaMoveRow( textarea , input.value );
    });
    samplebutton.addEventListener("click",()=>{
        textarea.value = demosample.innerText;
    });
});

samplebuttonはデモのhtml上にありませんが、サンプル用の文字列を囲む要素のid属性としてセットされています。

 

解説

textareaには、指定範囲を選択するsetSelectionRange()メソッドがあります。

setSelectionRange()メソッドの構文

textarea.setSelectionRange( selectionStart, selectionEnd )

selectionStartとselectionEndは、textarea内の先頭から数えた文字位置です。
selectionStartとselectionEndの値が異なる時は、その範囲を選択して、カーソルを移動します。
同じときは、その位置へカーソルを移動します。

詳しくは、次のページを読んでみてください。
【JavaScript】 inputまたはtextarea内のテキスト選択を制御する方法

今回は行への移動なので、行の先頭の文字位置を確認して、その位置へ移動します。

方法としては正規表現で改行を順番に取得します。
textareaの改行はLF("\n")で統一されているので正規表現は /\n/ ですが、もしかしたら他のコードがあるかもしれないという少し小心な気持ちから、/\r\n|\n|\r/ になっています。

JavaScriptのマッチングにはStringのmatch()とRegExpのexec()メソッドがあります。
今回は、RegExpのexec()を使用します。

exec()で改行を指定された行数だけ取得できたら、exec()メソッドの戻り値のindexプロパティ+1へ移動します。
これで改行の直後、つまり次行の先頭にカーソルが移動します。

関数の使用例は、デモのスクリプトを見てください。

なお、setSelectionRange()メソッドが使用できない古いブラウザは、今回作成した関数は動きません。
当たり前ですが…

たぶん古いブラウザを考慮するのは、特殊なケース。
もう、古いブラウザは考えなくてもいいよね…

更新日:2023/04/05

書いた人(管理人):けーちゃん

スポンサーリンク

記事の内容について

null

こんにちはけーちゃんです。
説明するのって難しいですね。

「なんか言ってることおかしくない?」
たぶん、こんなご意見あると思います。

裏付けを取りながら記事を作成していますが、僕の勘違いだったり、そもそも情報源の内容が間違えていたりで、正確でないことが多いと思います。
そんなときは、ご意見もらえたら嬉しいです。

掲載コードについては事前に動作確認をしていますが、貼り付け後に体裁を整えるなどをした結果動作しないものになっていることがあります。
生暖かい視線でスルーするか、ご指摘ください。

ご意見、ご指摘はこちら。
https://note.affi-sapo-sv.com/info.php

 

このサイトは、リンクフリーです。大歓迎です。