SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

japan.internet.com翻訳記事

JavaScriptでDOMレンジを扱う

DOM Rangeを使ってドキュメントを細かく操作する

DOMレンジの内容の操作

 レンジを選択すると、内部的にドキュメントフラグメントノードが作成され、そこに選択内のすべてのノードがアタッチされます。ただし、この処理が行われる前に、選択内容が整形式であることが要求されます。

 先ほどの例に示したように、この方法では、途中に</b>終了タグを含んでいる、「Hello」の1つ目の「l」から「World」の「o」までの範囲を選択することができます(図4を参照)。このような選択は、『Professional JavaScript for Web Developers』(Nicholas C. Zakas 著、Wrox Pr Inc.、2005年4月)で説明されている通常のDOMメソッドでは不可能です。

図4
図4

 レンジを使ったときにこの制限を回避できるのは、レンジでは欠けている開始タグと終了タグが認識されるからです。前述の例では、選択内に<b>開始タグが足りないと判断されたため、レンジによって開始タグが動的に追加され、さらに「He」を閉じるための</b>終了タグが新たに追加されます。これにより、DOMは次のようになります。

<p><b>He</b><b>llo</b> World</p>

 このレンジに含まれるドキュメントフラグメントは図5のようになります。

図5
図5

 このドキュメントフラグメントが作成されると、レンジの内容をさまざまなメソッドで操作できるようになります。

 最もわかりやすく使いやすいのはdeleteContents()メソッドでしょう。このメソッドでは、レンジの内容をドキュメントから削除します。前述の例でレンジに対してdeleteContents()を呼び出すと、ページ内のHTMLは次のようになります。

<p><b>He</b>rld</p>

 ドキュメントフラグメント全体が削除されるので、そのままだと</b>タグが足りなくなりますが、レンジによって</b>タグが補われるため、ドキュメントは整形式に保たれます。

 extractContents()メソッドはdeleteContents()によく似ています。このメソッドでは、選択範囲をドキュメントから削除し、その範囲のドキュメントフラグメントを戻り値として返します。これにより、そのレンジの内容を他の場所に挿入することが可能になります。

var oP1 = document.getElementById("p1");
var oHello = oP1.firstChild.firstChild;
var oWorld = oP1.lastChild;
var oRange = document.createRange();
oRange.setStart(oHello, 2);
oRange.setEnd(oWorld, 3);
var oFragment = oRange.extractContents();
document.body.appendChild(oFragment);

 この例では、ドキュメントフラグメントを抽出した後、ドキュメントの<body/>要素の末尾に追加しています((ドキュメントフラグメントをappendChild()に渡したときは、そのフラグメント自身ではなく、フラグメントの子だけが追加されるので注意してください)。この例を実行すると、ページの先頭には<b>He</b>rldが、ページの末尾には<b>llo</b> Woが配置されます。

 また、cloneContents()メソッドを使用すると、ドキュメントフラグメントをその場に残したまま、そのフラグメントのコピーを作成して、ドキュメントの他の場所に挿入することができます。

var oP1 = document.getElementById("p1");
var oHello = oP1.firstChild.firstChild;
var oWorld = oP1.lastChild;
var oRange = document.createRange();
oRange.setStart(oHello, 2);
oRange.setEnd(oWorld, 3);
var oFragment = oRange.cloneContents();
document.body.appendChild(oFragment);

 このメソッドはextractContents()によく似ています(どちらもレンジのドキュメントフラグメントを返します)。この例を実行すると、ページの末尾に<b>llo</> Woが追加され、元のHTMLコードはそのまま残ります。

筆者注
 ドキュメントフラグメントとそのレンジ選択に対する変更は、上記のいずれかのメソッドが呼び出されるまでは発生しません。その時点までは、元のHTMLには何の変化もありません。

DOMレンジの内容の挿入

 前述の3つのメソッドでは、それぞれ異なる方法でレンジの情報を削除またはコピーしました。また別のメソッドを使用して、レンジに内容を追加することもできます。

 insertNode()メソッドでは、選択レンジの先頭にノードを挿入できます。たとえば、前のセクションで定義したレンジに次のHTMLコードを挿入することを考えてみましょう。

<span style="color: red">Inserted text</span>

 この処理は次のコードで実現できます。

var oP1 = document.getElementById("p1");
var oHello = oP1.firstChild.firstChild;
var oWorld = oP1.lastChild;
var oRange = document.createRange();
var oSpan = document.createElement("span");
oSpan.style.color = "red";
oSpan.appendChild(document.createTextNode("Inserted text"));

oRange.setStart(oHello, 2);
oRange.setEnd(oWorld, 3);
oRange.insertNode(oSpan);

 このJavaScriptを実行すると、次のHTMLコードが生成されます。

<p id="p1"><b>He<span style="color: red">Inserted text</span>llo</b>
              World</p>

 レンジ選択の前半部分である「Hello」の「llo」の直前に<span/>が挿入されていることに注目してください。また、元のHTMLで<b/>要素が追加も削除もされていないことに注意してください。これは、前のセクションで紹介したメソッドを使用していないからです。このテクニックは、役に立つ情報をページに挿入するときなどに利用できます(たとえば、新規ウィンドウで開くリンクを示すアイコンなど)。

 レンジに内容を挿入するだけでなく、surroundContents()メソッドを使用して、レンジを囲むように内容を挿入することもできます。このメソッドは、レンジの内容を囲むノードを引数として受け取ります。内部的には、次のような処理が行われます。

  1. レンジの内容が抽出されます(extractContents()と同様)。
  2. 元のドキュメント内で、レンジが置かれていた位置に指定のノードが挿入されます。
  3. ドキュメントフラグメントの内容が指定のノードに追加されます。

 この機能は、Webページ内の特定の単語を強調表示するときなどに役立ちます。次に例を示します。

var oP1 = document.getElementById("p1");
var oHello = oP1.firstChild.firstChild;
var oWorld = oP1.lastChild;
var oRange = document.createRange();
var oSpan = document.createElement("span");
oSpan.style.backgroundColor = "yellow";

oRange.setStart(oHello, 2);
oRange.setEnd(oWorld, 3);
oRange.surroundContents(oSpan);

 このコードを実行すると、選択レンジの背景が黄色で強調表示されます。

次のページ
DOMレンジの折りたたみ

この記事は参考になりましたか?

japan.internet.com翻訳記事連載記事一覧

もっと読む

この記事の著者

japan.internet.com(ジャパンインターネットコム)

japan.internet.com は、1999年9月にオープンした、日本初のネットビジネス専門ニュースサイト。月間2億以上のページビューを誇る米国 Jupitermedia Corporation (Nasdaq: JUPM) のニュースサイト internet.comEarthWeb.com からの最新記事を日本語に翻訳して掲載するとともに、日本独自のネットビジネス関連記事やレポートを配信。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

Nicholas C. Zakas(Nicholas C. Zakas)

Professional Ajax』(WROX, ISBN: 0-471-77778-1)および『Professional JavaScript for Web Developers』(WROX, ISBN: 0-7645-7908-8)の著者。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/1519 2007/08/10 11:43

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー