範囲を操作

範囲を操作するには、Rangeオブジェクトを使用します。
Rangeオブジェクトは、DOM上であるノードからあるノードまでを指定することで範囲とし、その範囲を取得したり置き換えたりといった操作を行うことのできる機能です。
また、Selectionオブジェクトと組み合わせることで範囲を選択したりすることもできます。

  • ※ IE8以下には対応していません。

初期定義(インスタンスの生成)

Rangeオブジェクトをnewキーワードを使用して、インスタンスを生成します。
操作を行う上で最低限必要になります。

構文

ES5

var range = new Range();

ES6以降

const range = new Range();

戻り値

生成されたインスタンスを返します。

サンプルコード

JavaScript (ES5)

var range = new Range();

JavaScript (ES6以降)

const range = new Range();

document.createRangeメソッドについて

同様の機能としてdocument.createRangeメソッドが存在しますが、これは古いブラウザに実装されたものです。
古いブラウザに対応する必要がある場合はこちらを使用してください。

JavaScript (ES5)

var range = document.createRange();

JavaScript (ES6以降)

const range = document.createRange();

範囲の指定

あるノードからあるノードまでの範囲を指定するには、Range.setStartメソッド、Range.setEndメソッドを使用します。
Range.setStartメソッドは範囲を開始するノード、Range.setEndメソッドは範囲を終了するノードを指定することができます。

構文:Range.setStartメソッド

Range.setStart(node, offset);
引数名 説明
第一引数
必須
node Node 範囲を開始するノード。
第二引数
必須
offset number

範囲を開始する位置を0以上の数値で指定する。
ノードの種類によって位置の基準が次のように変わる。

第一引数で指定したノードがテキスト系(Text、Comment、CDATASection)である場合、範囲を開始する位置を指定。

第一引数で指定したノードが要素(Element)である場合、範囲を開始する子ノードの番号を指定。

なお、数値に一致するノードが見つからない場合や、負の数値を指定すると例外が発生する。

構文:Range.setEndメソッド

Range.setEnd(node, offset);
引数名 説明
第一引数
必須
node Node 範囲を終了するノード。
第二引数
必須
offset number

範囲を開始する位置を0以上の数値で指定する。
ノードの種類によって位置の基準が次のように変わる。

第一引数で指定したノードがテキスト系(Text、Comment、CDATASection)である場合、範囲を終了する位置を指定。

第一引数で指定したノードが要素(Element)である場合、範囲を終了する子ノードの番号を指定。

なお、数値に一致するノードが見つからない場合や、負の数値を指定すると例外が発生する。

サンプルコード

HTML

<p>Lorem <b>ipsum</b> dolor <i>sit</i> amet.</p>

JavaScript (ES5)

var range         = new Range(),
    paragraphElem = document.getElementsByTagName('p')[0];

range.setStart(paragraphElem, 1);
range.setEnd(paragraphElem, 4);

JavaScript (ES6以降)

const range         = new Range(),
      paragraphElem = document.querySelector('p');

range.setStart(paragraphElem, 1);
range.setEnd(paragraphElem, 4);

上記のサンプルコードは次の図のような範囲になります。

ノードを範囲として指定

ノードを範囲として指定するには、Range.selectNodeメソッドを使用します。
これを使用することで、指定したノード全体を範囲として指定することができます。
Range.selectNodeメソッドを使用すると、指定したノードをもとに、開始と終了ノード、その位置が自動的に設定されます。

構文

Range.selectNode(node);

サンプルコード

JavaScript (ES5)

var range = new Range();

range.selectNode(document.getElementsByTagName('p')[0]);

JavaScript (ES6以降)

const range = new Range();

range.selectNode(document.querySelector('p'));

ノードの内側を範囲として指定

ノードの内側を範囲として指定するには、Range.selectNodeContentsメソッドを使用します。
これを使用することで、指定したノードの内側を範囲として指定することができます。
Range.selectNodeContentsメソッドを使用すると、指定したノードをもとに、開始と終了ノード、その位置が自動的に設定されます。

構文

Range.selectNodeContents(node);

サンプルコード

JavaScript (ES5)

var range = new Range();

range.selectNodeContents(document.getElementsByTagName('p')[0]);

JavaScript (ES6以降)

const range = new Range();

range.selectNodeContents(document.querySelector('p'));

範囲の開始または終了のノードを取得

範囲の開始または終了のノードを取得するには、開始ノードはRange.startContainerプロパティ、終了ノードはRange.endContainerプロパティを使用します。

構文:Range.startContainer

ES5

var node = Range.startContainer;

ES6以降

const node = Range.startContainer;

戻り値

取得した開始ノードを返します。

構文:Range.endContainer

ES5

var node = Range.endContainer;

ES6以降

const node = Range.endContainer;

戻り値

取得した終了ノードを返します。

サンプルコード

JavaScript (ES5)

var range = new Range();

range.setStart(document.getElementsByTagName('p')[0], 1);
range.setEnd(document.getElementsByTagName('h2')[0], 4);

var node = range.startContainer;

JavaScript (ES6以降)

const range = new Range();

range.setStart(document.querySelector('p'), 1);
range.setEnd(document.querySelector('h2'), 4);

const node = range.startContainer;

範囲の開始または終了の位置を取得

範囲の開始または終了の位置を取得するには、開始位置はRange.startOffsetプロパティ、終了位置はRange.endOffsetプロパティを使用します。

構文:Range.startOffset

ES5

var position = Range.startOffset;

ES6以降

const position = Range.startOffset;

戻り値

取得した開始位置を返します。

構文:Range.endOffset

ES5

var position = Range.endOffset;

ES6以降

const position = Range.endOffset;

戻り値

取得した終了位置を返します。

サンプルコード

JavaScript (ES5)

var range         = new Range(),
    paragraphElem = document.getElementsByTagName('p')[0];

range.setStart(paragraphElem, 1);
range.setEnd(paragraphElem, 4);

alert(range.startOffset);

JavaScript (ES6以降)

const range         = new Range(),
      paragraphElem = document.querySelector('p');

range.setStart(paragraphElem, 1);
range.setEnd(paragraphElem, 4);

console.log(range.startOffset);

範囲の開始と終了が同じか判定

範囲の開始と終了が同じか判定するには、Range.collapsedプロパティを使用します。
開始と終了のノードと位置が、完全に一致するかどうかを判定します。

構文

ES5

var result = Range.collapsed;

ES6以降

const result = Range.collapsed;

戻り値

範囲の開始と終了が同じ場合はtrue、そうでなければfalseを返します。

サンプルコード

JavaScript (ES5)

var range         = new Range(),
    paragraphElem = document.getElementsByTagName('p')[0];

range.setStart(paragraphElem, 1);
range.setEnd(paragraphElem, 1);

alert(range.collapsed); // ノードも位置も同じためtrueを返す

JavaScript (ES6以降)

const range         = new Range(),
      paragraphElem = document.querySelector('p');

range.setStart(paragraphElem, 1);
range.setEnd(paragraphElem, 1);

console.log(range.collapsed); // ノードも位置も同じためtrueを返す

範囲をノードで囲う

範囲をノードで囲うには、Range.surroundContentsメソッドを使用します。

囲うノードがテキストの場合、範囲は囲うノードに置き換わり、さらに例外が発生します。

構文

Range.surroundContents(node);

サンプルコード

JavaScript (ES5)

var range         = new Range(),
    paragraphElem = document.getElementsById('p')[0],
    markElem      = document.createElement('mark');

range.setStart(paragraphElem, 1);
range.setEnd(paragraphElem, 4);

range.surroundContents(markElem);

JavaScript (ES6以降)

const range         = new Range(),
      paragraphElem = document.querySelector('p'),
      markElem      = document.createElement('mark');

range.setStart(paragraphElem, 1);
range.setEnd(paragraphElem, 4);

range.surroundContents(markElem);

範囲を削除

範囲を削除するには、Range.deleteContentsメソッドを使用します。
解除ではなく削除であることに注意してください。

構文

Range.deleteContents();

サンプルコード

JavaScript (ES5)

var range         = new Range(),
    paragraphElem = document.getElementsById('p')[0];

range.setStart(paragraphElem, 1);
range.setEnd(paragraphElem, 4);

range.deleteContents();

JavaScript (ES6以降)

const range         = new Range(),
      paragraphElem = document.querySelector('p');

range.setStart(paragraphElem, 1);
range.setEnd(paragraphElem, 4);

range.deleteContents();

範囲のノードを複製

範囲のノードを複製するには、Range.cloneContentsメソッドを使用します。

構文

ES5

var node = Range.cloneContents();

ES6以降

const node = Range.cloneContents();

戻り値

複製したノードをDocumentFragmentオブジェクトで返します。

サンプルコード

JavaScript (ES5)

var range         = new Range(),
    paragraphElem = document.getElementsById('p')[0];

range.setStart(paragraphElem, 1);
range.setEnd(paragraphElem, 4);

var node = range.cloneContents();

JavaScript (ES6以降)

const range         = new Range(),
      paragraphElem = document.querySelector('p');

range.setStart(paragraphElem, 1);
range.setEnd(paragraphElem, 4);

const node = range.cloneContents();

範囲のノードを複製し元の範囲のノードを削除

範囲のノードを複製し元の範囲のノードを削除するには、Range.extractContentsメソッドを使用します。
Range.cloneContentsメソッドとRange.deleteContentsメソッドを実行したのと同じ結果になります。

構文

ES5

var node = Range.extractContents();

ES6以降

const node = Range.extractContents();

戻り値

範囲元を複製したノードをDocumentFragmentオブジェクトで返します。

サンプルコード

JavaScript (ES5)

var range         = new Range(),
    paragraphElem = document.getElementsById('p')[0];

range.setStart(paragraphElem, 1);
range.setEnd(paragraphElem, 4);

var node = range.extractContents();

JavaScript (ES6以降)

const range         = new Range(),
      paragraphElem = document.querySelector('p');

range.setStart(paragraphElem, 1);
range.setEnd(paragraphElem, 4);

const node = range.extractContents();

範囲の開始位置にノードを挿入

範囲の開始位置にノードを挿入するには、Range.insertNodeメソッドを使用します。

構文

Range.insertNode(node);

サンプルコード

JavaScript (ES5)

var range         = new Range(),
    paragraphElem = document.getElementsById('p')[0],
    newElem       = document.createElement('b');

range.setStart(paragraphElem, 1);
range.setEnd(paragraphElem, 4);

newElem.textContent = 'あいうえお';
range.insertNode(newElem);

JavaScript (ES6以降)

const range         = new Range(),
      paragraphElem = document.querySelector('p'),
      newElem       = document.createElement('b');

range.setStart(paragraphElem, 1);
range.setEnd(paragraphElem, 4);

newElem.textContent = 'あいうえお';
range.insertNode(newElem);

範囲を複製

範囲を複製するには、Range.cloneRangeメソッドを使用します。

構文

ES5

var range = Range.cloneRange();

ES6以降

const range = Range.cloneRange();

戻り値

複製された範囲のRangeオブジェクトを返します。

サンプルコード

JavaScript (ES5)

var range         = new Range(),
    paragraphElem = document.getElementsById('p')[0];

range.setStart(paragraphElem, 1);
range.setEnd(paragraphElem, 4);

var newRange = range.cloneRange();

JavaScript (ES6以降)

const range         = new Range(),
      paragraphElem = document.querySelector('p');

range.setStart(paragraphElem, 1);
range.setEnd(paragraphElem, 4);

const newRange = range.cloneRange();

範囲の開始と終了を直前または直後で設定

範囲の開始と終了を直前または直後で設定するには、Range.setStartBeforeメソッド、Range.setStartAfterメソッド、Range.setEndBeforeメソッド、Range.setEndAfterメソッドの何れかを使用します。

Range.setStartBeforeメソッドは開始の直前、Range.setStartAfterメソッドは開始の直後、Range.setEndBeforeメソッドは終了の直前、Range.setEndAfterメソッドは終了の直後として範囲を設定します。

構文:Range.setStartBefore

Range.setStartBefore(node);
引数名 説明
第一引数
必須
node Node 直前に開始する範囲のノード。

構文:Range.setStartAfter

Range.setStartAfter(node);
引数名 説明
第一引数
必須
node Node 直後に開始する範囲のノード。

構文:Range.setEndBefore

Range.setEndBefore(node);
引数名 説明
第一引数
必須
node Node 直前に終了する範囲のノード。

構文:Range.setEndAfter

Range.setEndAfter(node);
引数名 説明
第一引数
必須
node Node 直後に終了する範囲のノード。

サンプルコード

JavaScript (ES5)

var range = new Range();

range.setStartBefore(document.getElementsById('p')[0]);

JavaScript (ES6以降)

const range = new Range();

range.setStartBefore(document.querySelector('p'));

範囲を文字列として取得

範囲を文字列として取得するには、toStringメソッドを使用します。
タグが削除され文字列だけを取得することができます。

構文

ES5

var str = Range.toString();

ES6以降

const str = Range.toString();

戻り値

範囲の文字列を返します。

サンプルコード

JavaScript (ES5)

var range         = new Range(),
    paragraphElem = document.getElementsById('p')[0];

range.setStart(paragraphElem, 1);
range.setEnd(paragraphElem, 4);

alert(range.toString());

JavaScript (ES6以降)

const range         = new Range(),
      paragraphElem = document.querySelector('p');

range.setStart(paragraphElem, 1);
range.setEnd(paragraphElem, 4);

console.log(range.toString());

開始ノードと終了ノードに共通する最も近い先祖ノードを取得

開始ノードと終了ノードに共通する最も近い先祖ノードを取得するには、Range.commonAncestorContainerプロパティを使用します。

構文

ES5

var node = Range.commonAncestorContainer;

ES6以降

const node = Range.commonAncestorContainer;

戻り値

最も近い先祖ノードを返します。
もし、開始ノードまたは終了ノードが、片方のノードの子孫要素である場合はそのもう片方のノードを返します。

サンプルコード

HTML

<div class="foo">
	<p>Lorem <b>ipsum</b> dolor <i>sit</i> amet.</p>

	<section>
		<h2>Heading 2</h2>
		<p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Architecto omnis iusto tempora nostrum! Ratione ad obcaecati soluta voluptates iste architecto, tenetur laboriosam laborum itaque ullam animi qui facilis nulla neque?</p>
	</section>
</div>

JavaScript (ES5)

var range = new Range();

range.setStart(document.getElementsByTagName('p')[0], 1);
range.setEnd(document.getElementsByTagName('h2')[0], 1);

var node = range.commonAncestorContainer; // div.fooノードを返す

JavaScript (ES6以降)

const range = new Range();

range.setStart(document.querySelector('p'), 1);
range.setEnd(document.querySelector('h2'), 1);

const node = range.commonAncestorContainer; // div.fooノードを返す

選択状態にする

範囲を選択状態にするには、SelectionオブジェクトのSelection.addRangeメソッドを使用することで、選択状態にすることができます。
Selectionオブジェクトはwindow.getSelectionメソッドを使用することで、参照することができます。

サンプルコード

JavaScript (ES5)

var range         = new Range(),
    paragraphElem = document.getElementsByTagName('p')[0],
    selection     = window.getSelection();

range.setStart(paragraphElem, 1);
range.setEnd(paragraphElem, 4);

// 現在の選択状態を解除
selection.removeAllRanges();

// 選択状態
selection.addRange(range);

JavaScript (ES6以降)

const range         = new Range(),
      paragraphElem = document.querySelector('p'),
      selection     = window.getSelection();

range.setStart(paragraphElem, 1);
range.setEnd(paragraphElem, 4);

// 現在の選択状態を解除
selection.removeAllRanges();

// 選択状態
selection.addRange(range);

JavaScript逆引きリファレンス一覧へ戻る