JavaScript

contenteditableな要素でキャレット(カーソル)を文末に移動させる

みなさん、こんにちは。どんぶらっこです。

今日は、キャレットを移動させる方法について解説します!

グランくん
グランくん
キャレット…って何?
どんぶラッコ
どんぶラッコ
文章を入力している時とかに出てくる棒線のことだよ!

今日はこの位置をjavascript側で移動させたい…という(ニッチな)要望に答えていきます!

サンプルコード

See the Pen カーソル(キャレット)の位置を移動するサンプル by cha1ra (@cha1ra) on CodePen.

適当な位置にキャレットを仕込んだ後、「行末に移動」ボタンをクリックするとキャレットが移動する様子がわかると思います。

この挙動を実現しているのが↓↓の部分です。

const memo = document.querySelector('#memo')

moveButton.addEventListener('click', function(){
  const selection = window.getSelection()
  const range = document.createRange()
  const offset = memo.innerText.length
  range.setStart(memo.firstChild, offset)
  range.setEnd(memo.firstChild, offset)
  selection.removeAllRanges()
  selection.addRange(range)
})

getSelection() メソッドは現在選択中の情報、 selection オブジェクトを返してくれるメソッドです。

試しに、キャレットが出ている状態で下記JavaScriptを実行してみてください。

const selection = window.getSelection()
console.log(selection.type)

すると、Caret と表示されるはずです。つまりキャレットの情報を所持しているわけですね。

余談ですが、

window.getSelection().getRangeAt(0)

のように書くと、現在選択中の Range オブジェクトを書くことができます。

このrangeを書き換えてあげることで、キャレットの位置を移動させることができます。

その方法は、

新しい Range オブジェクトを作る → 現在の Rangeを削除 → 新規 Rangeを追加する

というものです。

先ほどのサンプルプログラムで言うと、下記の部分になります。

  const range = document.createRange() // 新しい Rangeオブジェクト
  const offset = memo.innerText.length // 今回は行末に移動したいので文字長を取得
  range.setStart(memo.firstChild, offset) // キャレットの開始位置を設定
  range.setEnd(memo.firstChild, offset) // キャレットの終了位置を設定
  selection.removeAllRanges() // 現在のrangeをクリア
  selection.addRange(range) // rangeを追加
グランくん
グランくん
さっきのプログラムはほぼほぼ書き換えパートだったんだね!

筆者は理解するのに時間がかかりましたが、慣れたら簡単に思える…そんなプログラムでした。

みなさんも使ってみてください♪

\面白いと思ったら/

記事のシェア & Twitter のフォロー をお願いします!

@proglearn
一緒によく読まれている記事

COMMENT

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です