範囲を操作
範囲を操作するには、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);