JavaScript Examples
第22回 Nodeインターフェイスを利用する

今回も「Nodeインターフェイス」についてみていきたい。これまでは 主にノードの追加削除といった方法を見てきたが、今回はツリーとしての ノードの特徴である階層に関連する処理などでまだ紹介していないもの についてながめていきたい。




■ツリー状の親子関係

 ノードはHTMLをツリー(樹木)構造のものと
してとらえた時のいわばその樹にぶらさがる
すべてのものだ。たとえば、下記のようなHTML
の場合は

  <p id="pid"><i>test1</i><b>test2</b></p>
次のような構造になっている。
    <p>┬<i>─test1      └<b>─test2
 この時、<i>と<b>はともに<p>の子供で、 <i>は最初の子供だからfirstChildと呼び、 <b>は最後の子だからlastChildと呼ぶ。  もし仮に、<p>のid名ががpidという名前 だったら、<i>は
    oj = document.getElementById('pid')   alert( oj.firstChild.nodeName )

↑このスクリプトサンプル ./sample/f1.htm
などのようにid名で検索してその最初の子( firstChild)として取り出すことができる。 nodeNameはノードの名前を返すが<i>タグの ような場合は「I」というタグ名を返す。<--型別一覧は下記  また、この<p>がページで最初のものなら、
  oj = document.getElementsByTagName('P')   alert( oj.item(0).firstChild.nodeName )

↑このスクリプトサンプル ./sample/f3.htm (関連サンプル ./sample/f2.htm)
このように、getElementsByTagNameによりペ ージ内にあるタグ名のすべての<p>のリスト 配列を取り出してから、その最初の(item(0)) の<p>タグの子として取り出したりもできる。  さらに、もう一段階層を下がった「test1」 という文字列は<i>のfirstChildであると同 時に<i>は「test1」しか子供を持っていない のでlastChildでもあり、「test2」は<b>の firstChildでlastChildだ。  では、子供ではなく親ノードはどうすれば よいだろう? childの親だから...そう、Java Scriptではおなじみの言い回しparentを使っ てparentNodeでOKだ。上記HTMLの場合は、 <i>や<b>からみて親ノードである<p>はparen tNodeということで、
  oj = document.getElementsByTagName('I')   alert( oj.item(0).parentNode.nodeName )

↑このスクリプトサンプル ./sample/f4.htm
このようにしてアクセスできることになって いる。 ■ノードの兄弟関係  ツリー状のノードは、親-子-孫といったつ ながりになっているわけだが、それぞれの世 代?レベルには兄弟(姉妹)も存在している。 DOMツリーは親子関係だけではなく兄弟方向へも アクセスが可能だ。親子兄弟へのアクセスを把握 すれば、どんな位置からでも、どこへでもたどり 着くことができる。  前ページの例でいえば、<i>と<b>はともに <p>の子供である。つまり、兄弟だ。この時、 <i>からみた<b>をDOMでは
  nextSibling
というプロパティ(DOM用語ではアトリビュー ト)で表すことができる。「Sibling」とは、 英語で男女の区別をつけない兄弟という意味 だ。nextSiblingといえば文字通り「次の兄 弟」という意味になる。たとえば、
  poj = document.getElementById('pid')   ioj = poj.firstChild   //←<i>   boj = ioj.nextSibling  //←<b>   alert( boj.nodeName )

↑このスクリプトサンプル ./sample/f5.htm
こうすると、<b>のnodeNameであるタグ名「B」 がダイアログに表示される。  では、逆に「前の兄弟」はどうだろう? そう、これも英語で「前の」という意味の単 語「previous」を使って、
  previousSibling
と表現されている。したがって、
  poj = document.getElementById('pid')   boj = poj.lastChild        //←<b>   ioj = boj.previousSibling  //←<i>   alert( ioj.nodeName )

↑このスクリプトサンプル ./sample/f6.htm
型別nodeName,nodeValue,attributesの値一覧
Interface nodeName nodeValue attributes
Attr attribute名 attribute値 null
CDATASection "#cdata-section" content of the CDATA Section null
Comment "#comment" content of the comment null
Document "#document" null null
DocumentFragment "#document-fragment" null null
DocumentType document type 名 null null
Element tag名 null NamedNodeMap
Entity entity名 null null
EntityReference entity referenced名 null null
Notation notation名 null null
ProcessingInstruction target entire content excluding the target null
Text "#text" content of the text node null
書式
oj.nodeName

オブジェクト
oj
対象ノード
説明
ノードの名前。戻り値はnodeTypeによって異なる
戻り値
nodeName値
Attr アトリビュート名
CDATASection "#cdata-section"
Comment "#comment"
Document "#document"
DocumentFragment "#document-fragment"
DocumentType DocumentType名
Element タグ名
Entity エンティティ名
EntityReference 参照されるエンティティ名
Notation 表記法名
ProcessingInstruction ターゲット
Text "#text"

インターフェイス
/Core/Node
仕様
DOM1 /Core/Node/nodeName
DOM2 /Core/Node/nodeName
DOM3 /Core/Node/nodeName


書式
oj.getElementsByTagName( tagName )

オブジェクト
oj
document
引数
tagName

タグ名。ワイルドカード「*」も使用可能。「*」はすべてのタグをあらわす
説明
引数のタグ名を持つすべてのエレメントのノードリスト配列を返す。順序はDocumentのツリー順。
戻り値
合致したすべてのエレメントを含むNodeList
インターフェイス
/Core/Document
仕様
DOM1 /Core/Document/getElementsByTagName
DOM2 /Core/Document/getElementsByTagName
DOM3 /Core/Document/getElementsByTagName

書式
oj.getElementsByTagName( tagName )

オブジェクト
oj
対象エレメントノード
引数
tagName

タグ名。ワイルドカード「*」も使用可能。「*」はすべてのタグをあらわす
説明
引数のタグ名を持つすべての子孫エレメントのノードリスト配列を返す。順序はツリー順。
戻り値
合致したすべてのエレメントを含むNodeList
インターフェイス
/Core/Element
仕様
DOM1 /Core/Element/getElementsByTagName
DOM2 /Core/Element/getElementsByTagName
DOM3 /Core/Element/getElementsByTagName

書式
oj.nextSibling

オブジェクト
oj
対象ノード
説明
対象となるノードの直後にある兄弟ノード
戻り値
直後のノード。無ければnull。
インターフェイス
/Core/Node
仕様
DOM1 /Core/Node/nextSibling
DOM2 /Core/Node/nextSibling
DOM3 /Core/Node/nextSibling

書式
oj.previousSibling

オブジェクト
oj
対象ノード
説明
対象となるノードの直前にある兄弟ノード
戻り値
直前のノード。無ければnull。
インターフェイス
/Core/Node
仕様
DOM1 /Core/Node/previousSibling
DOM2 /Core/Node/previousSibling
DOM3 /Core/Node/previousSibling
ノードのクローンを作って操作する ■クローンを作る  あるHTMLツリーのひとかたまりをまとめて コピーする方法がある。たとえば、
  <p id="pid">     <img src="./usa.gif">     <b>リス園のうさぎ</b>   </p>
このHTMLは次のスクリプトでクローンを作成 し好きな場所へコピーすることができるよう になる。
  clone = document.getElementById('pid').cloneNode(true)
このようにして作られたクローンノードはこ れまで紹介してきたcreateElement()などで 生成されたノードのようにapendChild()や insertBefor()などによってHTMLツリー内に 追加したり削除したりすることができる。  したがって、たとえば次のように書くと
  <div    onmouseover="this.appendChild(clone)"   >この文字にカーソルが触ると、    クローンがコピーされます   </div>

↑このスクリプトサンプル ./sample/f7.htm
<p>タグ内の画像も<b>タグ内の「リス園のう さぎ」という文字もすべてが<div>タグの中 へコピーされることになる。  この時、cloneNode(引数)の引数はtrueなら サブディレクトリまでコピーし、falseなら 該当ノードだけをコピーする(該当ノードだ けなので文字列などもコピーしない)。 ■クローンを加工する  クローンもノードだからいままでのように いろいろな加工が可能だ。ざっくりとHTMLブ ロックをコピーしてその一部にだけ手を加え てから表示する、といった使い方なども可能 になるわけだ。
  img = clone.firstChild   imgsrc = img.attributes.getNamedItem('src')   imgsrc.nodeValue='saru.gif'

↑このスクリプトサンプル ./sample/f8.htm
と書くとクローン内の画像のsrc属性を書き 換えることができる。attributesは該当する エレメント(タグ)内の属性を集めた配列で、 上記のgetNamedItem('属性名')やitem(index 番号)などで該当属性を検索することができる。  上記サンプルでは、該当<img>タグのsrc 属性を検索し変数imgsrcへ収め、そのsrc属 性ノードの値を"saru.gif"へ書き換えること で画像を取り替えている。また、DOMはいろ いろな角度からの書き方ができるのが特徴で もあるが、他には次のような書き方もできる。
  img = clone.firstChild   imgsrc = img.setAttribute('src','saru.gif')
書式
oj.getElementById( id )

オブジェクト
oj
対象ノード
引数
id

id名
説明
id名で指定されたエレメントを返す。
戻り値
id名が一致するエレメント。なければnull
インターフェイス
/HTML/HTMLDocument (DOM1)
/HTML/Document (DOM2〜)
仕様
DOM1 /HTML/HTMLDocument/getElementById
DOM2 /HTML/Document/getElementById
DOM3 /HTML/Document/getElementById


書式
oj.cloneNode( deep )

オブジェクト
oj
対象ノード
引数
deep

trueならノード以下のツリーすべてをコピーする。falseなら該当ノードのみをコピーする(文字も含まない)。
説明
対象となるノードのコピーを返す。汎用的なコピーコンストラクタ。コピーノード自体は親をもたないのでparentNodeはnull。
戻り値
コピーノード
インターフェイス
/Core/Node
仕様
DOM1 /Core/Node/cloneNode
DOM2 /Core/Node/cloneNode
DOM3 /Core/Node/cloneNode


書式
oj.attributes

オブジェクト
oj
対象ノード
説明
対象がエレメントノードの場合に、そのエレメントが含む属性のリスト。
戻り値
NamedNodeMapのリスト。無ければnull。
インターフェイス
/Core/Node
仕様
DOM1 /Core/Node/attributes
DOM2 /Core/Node/attributes
DOM3 /Core/Node/attributes
■Sample   hoverした前後のノードも同時に書き換える ■Sample   触れた画像と前後の画像が拡大表示する ■Sample   生成されたカレンダーのクローンを作成する(Mac版IE5を除く) ■Sample   ボタンクリックで行を隣のテーブルへ移動する(Mac版IE5を除く) //////////////////////////////////////////////////////////////////// *上記サンプルは主に次の環境で動作するように作成されています ==================================================================== 動作環境 -------------------------------------------------------------------- Win n6 n7 moz e5 e6 o7, Mac n6 n7 moz e5 safari, Linux n6 n7 moz -------------------------------------------------------------------- //////////////////////////////////////////////////////////////////// 凡例 Win n3 -- NetscapeNavogator 3.x n4 -- NetscapeNavogator 4.x n6 -- NetscapeNavogator 6.x n7 -- NetscapeNavogator 7.x moz -- Mozilla e4 -- Internet Explorer 4.x e5 -- Internet Explorer 5.x e6 -- Internet Explorer 6.x o6 -- Opera 6.0 o7 -- Opera 7.0 Mac n3 -- NetscapeNavogator 3.x n4 -- NetscapeNavogator 4.x n6 -- NetscapeNavogator 6.x n7 -- NetscapeNavogator 7.x moz -- Mozilla e4.5 -- Internet Explorer 4.5 e5 -- Internet Explorer 5.0 または 5.1 safari -- Safari Linux n3 -- NetscapeNavogator 3.x n4 -- NetscapeNavogator 4.x n6 -- NetscapeNavogator 6.x n7 -- NetscapeNavogator 7.x moz -- Mozilla --------------------------------------------------------------------




●JavaScript 資料




Toshirou Takahashi tato@fureai.or.jp