SHOEISHA iD

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

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

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

japan.internet.com翻訳記事

JavaScriptでDOMレンジを扱う

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

DOMレンジによる複雑な選択

 複雑なレンジを作成するには、レンジのsetStart()メソッドとsetEnd()メソッドを使用する必要があります。どちらのメソッドも、参照ノードとオフセットという2つの引数を取ります。setStart()では、参照ノードはstartContainerに割り当てられ、オフセットはstartOffsetに割り当てられます。setEnd()の場合、参照ノードはendContainerに割り当てられ、オフセットはendOffsetに割り当てられます。

 これらのメソッドを使用して、selectNode()およびselectNodeContents()と同等の機能を実現することができます。たとえば、前の例に出てきたuseRanges()関数を、setStart()setEnd()を使って次のように書き換えることができます。

function useRanges() {
    var oRange1 = document.createRange();
    var oRange2 = document.createRange();
    var oP1 = document.getElementById("p1");
    var iP1Index = -1;
    for (var i=0; i < oP1.parentNode.childNodes.length; i++) {
        if (oP1.parentNode.childNodes[i] == oP1) {
            iP1Index = i;
            break;
        }
    }

    oRange1.setStart(oP1.parentNode, iP1Index);
    oRange1.setEnd(oP1.parentNode, iP1Index + 1);
    oRange2.setStart(oP1, 0);
    oRange2.setEnd(oP1, oP1.childNodes.length);
    //textbox assignments here
}

 ノードを選択する(oRange1)には、まず目的のノード(oP1)について、その親ノードのchildNodesコレクションにおけるインデックスを特定する必要があります。ノードの内容を選択する(oRange2)には、特に計算は必要ありません。もっとも、既にご存知のとおり、ノードやノードの内容を選択するにはもっと簡単な方法が他にあります。この方法のポイントは、ノードの一部だけを選択できるということです。

 たとえば、<p id="p1"><b>Hello</b> World</p>というHTMLコードから、「Hello」の「llo」だけと「World」の「Wo」だけを選択したい場合を考えてみましょう。この方法を使えば、これを簡単に実現できます。

 まず、通常のDOMメソッドを使用して、「Hello」と「World」を含む2つのテキストノードの参照を取得します。

var oP1 = document.getElementById("p1");
var oHello = oP1.firstChild.firstChild;
var oWorld = oP1.lastChild;

 テキストノード「Hello」は、実際には<p/>の孫にあたるので(直接の親は<b/>)、oP1.firstChildによって<b/>を取得し、oP1.firstChild.firstChildによって目的のテキストノードを取得します。テキストノード「World」は<p/>の2番目の(かつ最後の)子なので、oP1.lastChildによって取得できます。

 次に、レンジを作成して適切なオフセットを設定します。

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);

 setStart()ではオフセットを2に設定します。これは、「Hello」中の1つ目の「l」は位置2にあたるからです(先頭の文字「H」は位置0です)。setEnd()ではオフセットを3に設定します。このオフセットには、選択しない最初の文字の位置を指定するので、「r」が登場する位置3を指定しています(図3に示すように、実は位置0のところにスペースが入っています)。

図3
図3

 oHellooWorldはどちらもテキストノードなので、これらのノードはこのレンジのstartContainerとendContainerに割り当てられます。これにより、startOffsetとendOffsetは、要素が渡されたときのように子ノードを探すのではなく、各ノードに含まれているテキストを探すようになります。commonAncestorContainerは、両方のノードを含んでいる最初の祖先である<p/>要素になります。

 当然ながら、ドキュメントのセクションを選択しただけでは何の役にも立たないので、この選択範囲に対して何らかの操作を行うことになります。以降では、この点について説明します。

次のページ
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」など、さまざまなカンファレンスを企画・運営しています。

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

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

メールバックナンバー