はじめに
文字列を選択するときに、後ろから選択しても前から選択したのと同じように扱いたい!という要求があったため、実装してみました。
やりたいこと
<p>
<span>ふるいけや</span>
<span>かわずとびこむ</span>
<span>みずのおと</span>
</p>
例えば、以上のような DOM 構造の文字列を以下のように選択すると、選択範囲の始点のノード(anchorNode
)と終点のノード(focusNode
)はそれぞれ次のようになります。
選択した範囲 | 始点ノード(anchorNode ) |
終点ノード(focusNode ) |
|
---|---|---|---|
前からの選択 | 「い」から「み」まで | <span>ふるいけや</span> | <span>みずのおと</span> |
後ろからの選択 | 「み」から「い」まで | <span>みずのおと</span> | <span>ふるいけや</span> |
このとき、「後ろからの選択」でも「前からの選択」と同じようにしたい、すなわち、「後ろからの選択」の始点ノードと終点ノードを入れ替えたいというのが今回のやりたいことになります。
書いたコード
以上のやりたいことに対して、以下のコードを書きました。
const selection = window.getSelection()
const range = selection.getRangeAt(0).cloneRange()
selection.removeAllRanges()
selection.addRange(range)
getRangeAt(0)
で取得したRange
オブジェクトですでに始点・終点のノードが逆転しているので、これを利用しています。
-
selection.getRangeAt(0).startContainer
... <span>ふるいけや</span> -
selection.getRangeAt(0).endContainer
... <span>みずのおと</span>
(Rangeでは前から選択したか後ろから選択したかどうかは気にせず、親要素における位置関係からstartContainer
とendContainer
を設定しているのでしょうか)