uhyohyo.net

JavaScript初級者から中級者になろう

二章第五回 木構造の操作:ノードの追加

このページの最終更新日:

今回は、前回とは逆に新しいノードを子に追加するということを解説します。

ノードを作る

まず、ノードを追加するには、追加するノードを新しく作る必要があります。その方法を解説します。

createElement

createElementというメソッドがあります。これは、要素名を指定することで、新しいHTMLElementを作って返すメソッドです。これはdocumentが持つメソッドです。つまり、次のように呼び出します。

document.createElement('p')

では、次のサンプルを見てください。

<!doctype html>
<html>
  <head>
    <title>test</title>
  </head>
  <body>
    <p id="aaaaa">t<strong>es</strong>t</p>

    <script type="text/javascript">
      var newelement = document.createElement('p');
      console.log(newelement);
    </script>
  </body>
</html>
        

変数newelementに、document.createElementの返り値を代入しています。それをconsole.logで表示するとp要素が表示されるので、p要素のオブジェクトができていることが分かります。

こうしてできたHTMLElementは、document.getElementByIdなどで取得したものと同じように扱うことができます。

ただし、ただできただけで、まだ木構造には加わっていません。そのため、このままではページ上に表示されません。そこで、これを木構造に追加する方法をこれから解説します。

ノードを追加する

まず、上のサンプルでのHTML全体の木構造を見てみましょう。

html
  • head
    • title
      • #text "test"
  • body
    • #text
    • script
      • #text "var newel〜…"

このようになっています。ちなみに、p要素とscript要素の間に#textがありますが、ここにあるのは改行です。上のHTMLにある<body><p>の間にある改行に対応しています。このように、改行があるだけでテキストノードが発生します(ただし、終了タグの前の改行はテキストノードにならないことになっています)。

今回はbody要素に追加しましょう。ここで、body要素のオブジェクトが必要になります。

body要素にid属性をつけて、getElementByIdで取得することもできますが、body要素の場合はもっとよい方法があります。それは、documentオブジェクトのbodyプロパティです。つまり、 document.bodyですね。実はbody要素はこのように取得することができます。今回はこれを使いましょう。

appendChild

ノードに子ノードを追加するには、appendChildというメソッドを使います。

このメソッドに引数を渡すと、そのノードの子ノードの一番最後に引数のノードが追加されます。

<!doctype html>
<html>
  <head>
    <title>test</title>
  </head>
  <body>
    <p id="aaaaa">t<strong>es</strong>t</p>

    <script type="text/javascript">
      var newelement = document.createElement('p');

      document.body.appendChild(newelement);
    </script>
  </body>
</html>

この場合、追加するのは新しく作ったp要素、つまりnewelementに代入されているものです。

これをbody要素の子ノードに追加するので、こうなります。

html
  • head
    • title
      • #text "test"
  • body
    • #text
    • script
      • #text "var newel〜…"
    • p

しかし、画面には何の変化もありません。それは、p要素がテキストノードを持っていないからです。p要素の中身が空なのでは、<p></p>を追加したのと同じです。

つまり、追加するp要素に、さらにテキストノードの子ノードを持たせる必要があるわけです。次は、これを解説します。

テキストノードを作成する

テキストノードを持たせるには、当然作る必要があります。テキストノードは、先に紹介したcreateElementでは作れません。別のメソッドを使います。

それは、createTextNodeです。これまた、documentが持つメソッドです。

<!doctype html>
<html>
  <head>
    <title>test</title>
  </head>
  <body>
    <p id="aaaaa">t<strong>es</strong>t</p>

    <script type="text/javascript">
      var newtextnode = document.createTextNode("新しいテキストノード");

      console.log(newtextnode.nodeValue);
    </script>
  </body>
</html>
        

引数を1つ持っていて、これは作るテキストノードの中身を指定します。

つまり、「新しいテキストノード」という中身を持つテキストノードを作っています。

できたテキストノードは戻り値として得ることができます。今回は、それをnewtextnodeに代入しています。

できたもののnodeValueプロパティ(二章第三回参照)を見てみるとその中身が表示されることから、これはテキストノードであることが分かります。

そして、これをp要素に追加するのは、さっきと同じappendChildです。


<!doctype html>
<html>
  <head>
    <title>test</title>
  </head>
  <body>
    <p id="aaaaa">t<strong>es</strong>t</p>

    <script type="text/javascript">
      var newelement = document.createElement('p');
      var newtextnode = document.createTextNode("新しいテキストノード");

      newelement.appendChild(newtextnode);
    </script>
  </body>
</html>

newelementの子ノードにnewtextnodeを追加しています。

このサンプルでは、newelementは独立した木構造を持っています。実際に画面に表示されている、html要素を頂点とした木構造とは別に、今作ったばっかりのp要素を頂点とした、次のような木構造があるのです。

p
  • #text "新しいテキストノード"

さて、この木構造を持ったノードを別のノードの親にすると、木構造がまとめてくっつきます。つまり、

html
  • head
    • title
      • #text "test"
  • body
    • #text
    • script
      • #text "var newel〜…"
    • p
      • #text "新しいテキストノード"

というようになります。実際にやってみましょう。

<!doctype html>
<html>
  <head>
    <title>test</title>
  </head>
  <body>
    <p id="aaaaa">t<strong>es</strong>t</p>

    <script type="text/javascript">
      var newelement = document.createElement('p');
      var newtextnode = document.createTextNode("新しいテキストノード");

      newelement.appendChild(newtextnode);
      document.body.appendChild(newelement);
    </script>
  </body>
</html>
        

newelementをbody要素にappendChildしています。

ここで、画面に「新しいテキストノード」と表示されました。上の図の通りになったのです。

ちなみに、まずp要素を作ってbody要素に追加してから、あとでp要素にテキストノードを追加しても結果は同じになります。

今回までで木構造の操作をかなり自由にできるようになりました。