Linuxなどのメモ書き

JavaScript Rangeの使い方


Rev.17を表示中。最新版はこちら

Rangeオブジェクトに関するメモ。

1.SelectionとRangeの関係

Selectionはカーソルの選択領域を示す。Rangeは1つの連続した選択領域を表しSelectionに格納されている。通常はSelectionの中にはRangeは1つだけ存在する。
分断された領域が複数選択されている場合は、Selectionは複数のRangeを持つ(以下参照)。

Selectionの中に複数のRangeが含まれるケース

Linux版FireFoxだと、designMode = "On"の時に図1のようにセルを選択できる。このような場合、選択した各々のセルが1つのRegionとなり、Selectionに3つのRangeが含まれることになる。

このような選択はIEやWindows版FireFoxではできなかった。この他に複数のRangeを持つ選択方法にどのようなものがあるかは不明。


図1 複数Range存在するケース


2.具体的な触り方(Mozilla系)

2.1 Selectionの取得

まずはSelectionを取得する。
var selection = window.getSelection();

2.2 Rangeの取得

Selection内の最初のRangeを取得するには以下のようにする。

var range = selection.getRangeAt(0);

Rangeの数はrangeCountプロパティで取得可能。
selection.rangeCount;

2.3 Rangeの取り扱い

Rangeから具体的な選択範囲を取得するには表1に示すプロパティを使う。


表1 Rangeオブジェクトのよく使うプロパティ
プロパティ
意味
startContainer選択開始位置のDOM Node
startOffset選択開始位置のstartContainer内でのオフセット
endContainer選択終了位置のDOM Node
endOffset選択終了位置のendContainer内でのオフセット

DOM仕様書にこれらのプロパティについて図解入りで説明がありわかりやすい。


文字を選択した時に表1のプロパティがどのように変化するかを表示するサンプル。
http://www.bit-hive.com/~tomita/RangeDump/

JavaScriptのソースはhttp://www.bit-hive.com/~tomita/RangeDump/range.js

3. 具体的な触り方(IEの場合)

3.1 Rangeの取得

IEの場合Selectionはdocument内に既にあるので以下のようにして取得できる。
var range = document.selection.createRange();

3.2 Rangeの取り扱い

IEではMozilla系のようにstartContainerなどのプロパティは存在しない。IEのRangeオブジェクトの仕様はこちらを参照。

textプロパティで選択範囲の文字列を取得したり、pasteHTML()メソッドで選択範囲にHTMLを貼り付けたりできる。

4. サンプル

実際にRangeオブジェクトを使ったサンプル。

このサンプルはIFRAME内の選択領域にHTMLオブジェクトを挿入するコードを以下に示す。

IEではcreateRange()でRangeオブジェクトを取ってしまえば、pasteHTML()で張りつけることができる。Mozilla系では選択範囲のDOMオブジェクトを操作する必要がある。

IE用コード
function insertHTMLforIE(html)
{
// iframeのdocument,windowを取得
var win = frames['frame'].window;
var doc = frames['frame'].document;

win.focus();

range = doc.selection.createRange();
try {
range.pasteHTML(html);
} catch (e) {
alert(e);
}
}


Mozilla系用のコード
function insertHTMLForMozilla(html)
{
// iframeのdocumentとwindowを取得
var win = document.getElementById('frame').contentWindow;
var doc = document.getElementById('frame').contentDocument;

var fragment = doc.createDocumentFragment();
var div = doc.createElement("div");
div.innerHTML = html;

// div配下のNodeをfragmentに移動
while (div.firstChild) {
fragment.appendChild(div.firstChild);
}

var selection = win.getSelection();

range = selection.getRangeAt(0);

// 選択範囲の削除
range.deleteContents();

var container = range.startContainer;
var offset = range.startOffset;

switch (container.nodeType) {
case 1:
// Element node
container.insertBefore(fragment,
container.childNodes[offset]);
break;
case 3:
// Text node
var node = container.splitText(offset);
node.parentNode.insertBefore(fragment, node);
break;
}
}


実働サンプル:
http://www.bit-hive.com/~tomita/RangeInsert/

JavaScriptのソース:
http://www.bit-hive.com/~tomita/RangeInsert/insert.js


最終更新 2006/06/16 01:04:51 - kztomita
(2006/06/15 20:39:56 作成)
添付ファイル
multirange.png - kztomita


リンク

その他のWiki
Linuxメモ
Xnuメモ

会社
(有)ビットハイブ
受託開発やってます。

よくやる仕事

・Webシステム開発(LAMP環境)
・Linuxサーバー設定関連
サーバー移転作業代行

開発事例にデジタルカタログ/マンガビューワーを追加しました。

draggable.jsのスマホ対応版デモページを追加しました。説明はこちら

検索

Adsense
最近のコメント