HTML CSS JavaScript 基礎編-第4回 JavaScript基礎(2)-Dom編

:::note info
仕事で、Plotly.jsを使ってデータを可視化する必要があるため、JavaScriptに詳しくない私は、HTML、CSS、JavaScriptについての書籍を勉強して基本的な知識を身につけておくことにしました。自分ためのメモですので、記事の中で一部中国語で書くことがあります。また、自分にとって重要ではないところも飛ばしています。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3327130/595b81f8-0a72-83c3-4c8e-d7320ef8416f.png" width=160>
:::

# 1.DOM基礎編

## Domってなに？

DomがDocument Object Modelの略語です。W3Cが定義した標準です。

DOMがツリーの構造でHTMLの画面を表しています。ツリーでのノードがHTML画面での要素です。例えば、以下の例で：

```HTML
<!DOCTYPE html>
<html>
	<head>
        <meta charset="utf-8"/>
        <title></title>    
    </head>
	<body>
        <h1>おはようございます。</h1>
        <p style="color: red;">文字の色を赤に指定</p>
        <p>こんばんは。</p>
	</body>
</html>
```

DOM構造が以下の通りです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3327130/ba9925cc-725b-99b1-a37e-d8dbe0907327.png)

## ノードタイプ

Javascriptには、数多くのノードタイプがあります。Domのノードも１２種類がありますが、よく使われているのは３種類です。
- 要素ノード（nodeTYpe:1）
- 属性ノード（nodeTYpe:2）
- テキストノード（nodeTYpe:3）

例えば `<div id="pid001">おはようございます！</div>`で、全体が**要素ノード**、id部分が**属性ノード**、おはようございます部分が`テキストノード`です。
この三つのノードとも、それぞれ独立なノードです。属性ノートとテキストノードには、子ノードがありません。

## 要素ノードの取得

以下の関数で、指定の要素ノードの取得が可能です。

- getElementById()：idから取得、一つの要素
- getElementsByTagName():Tag名から取得、複数の要素

例１：idやTagnameから要素取得：

```html
<html>
    <head>
        <script>
            window.onload = function()
            {
                // idから取得
                var oDiv = document.getElementById("div1");
                oDiv.style.color = "red";

                // li-list1
                var oUI1 = document.getElementById("list1");
                var oLi1 = oUI1.getElementsByTagName("li");
                oLi1[2].style.color = "blue";

                // 次のli-list2
                var arr = ["東京","神奈川","千葉","大阪"]
                var oUI2 = document.getElementById("list2");
                var oLi2 = oUI2.getElementsByTagName("li");

                for(var i=0;i<oLi2.length;i++)
                {
                    oLi2[i].innerHTML = arr[i];
                    oLi2[i].style.color = "orange";
                }
            }
        </script>
    </head
    <body>
        <div id="div1">おはよう！ </div>  
        <ul id="list1">
            <li>HTML</li>
            <li>CSS</li>
            <li>Javascript</li>
            <li>JQuery</li>
            <li>Vue.js</li>
        </ul>

        <ul id="list2">
            <li></li>
            <li></li>
            <li></li>
            <li></li>
        </ul>
    </body>
</html>
```

**結果：**
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3327130/2950d538-5d54-bf49-088e-326d9203a6b5.png" width=480>

例２：動的に要素の作成や属性変更

```html
<html>
    <head>
        <script>
            window.onload = function()
            {
                document.body.innerHTML="<input type='button' id='bt1' value='ボタン'/><input type='button' value='ボタン'/><input type='button' value='ボタン'/>"
                var oBtn = document.getElementsByTagName("input");
                
                var oBtn1 = document.getElementById("bt1");
                oBtn[2].onclick = function()
                {
                    alert("要素数：" + oBtn.length);   
                }

                oBtn1.onclick = function()
                {
                    oBtn[2].style.color = "red";
                    oBtn1.style.color = "blue";
                }
            }
        </script>
    </head
    <body>
    </body>
</html>
```

bt1が押されたら、色も変わります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3327130/e02aa8a1-8de9-b200-a000-0db561dba3f3.png" width=480>

- getElementsByClassName()：ClassNameで複数要素の取得
上記のIDとTagnameからの取得の関数と似ています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3327130/c3295fb0-e354-e531-7165-c3b2d2981d55.png)



- querySelector() と querySelectorAll()
    - querySelector("セレクター")：条件に満たせた一つ目の要素
    - querySelector("セレクター")：条件に満たせた複数要素
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3327130/03330b9c-8e53-a315-6774-a6fdb0372ea4.png)

- getElementsByName()
フォーム要素では、nameというの属性があります、name属性から複数の要素を取得できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3327130/155f7465-6d97-c566-e373-458c15def8e3.png)


- document.title と document.body

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3327130/a1fc6775-cfb8-7ce3-0927-7a6697fd89ec.png)

## 動的に要素の作成

簡単な要素ノードの作成、テキストノードの挿入：

```html
<html>
    <head>
        <script>
            window.onload = function()
            {
                var oDiv = document.getElementById("content");
                var oStrong = document.createElement("strong");
                var oTxt = document.createTextNode("おはよう！")

                // テキストノードをStrong要素に挿入
                oStrong.appendChild(oTxt);
                // Strong要素をdiv要素に挿入
                oDiv.appendChild(oStrong);

                //
            }
        </script>
    </head
    <body>
        <div id="content"></div>
        <div id="content2"><strong>おはよう！</strong></div>
    </body>
</html>
```

動的にテーブルを作成する例：

```html
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
    <style type="text/css">
        table {border-collapse:collapse;}
        tr,td
        {
            width:80px;
            height:20px;
            border:1px solid gray;
        }
    </style>
    <script>
        window.onload = function ()
        {
            //動的にテーブルの作成
            var oTable = document.createElement("table");
            for (var i = 0; i < 3; i++)
            {
                var oTr = document.createElement("tr");
                for (var j = 0; j < 2; j++)
                {
                    var oTd = document.createElement("td");
                    oTd.innerText="(" + i + "," + j + ")";
                    oTr.appendChild(oTd);
                }
                oTable.appendChild(oTr);
            }
            //bodyに追加
            document.body.appendChild(oTable);
        }
    </script>
</head>
<body>
</body>
</html>
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3327130/a366f4f7-e8b5-7d0e-abc1-17c707d8d4c2.png)

## 纏め：

- 要素ノードの追加：`createElement()`
- テキストノードの作成：`createTextNode()`
- テキストノードを要素ノードに追加：`appendChild()`
- 作成した要素ノードを既存の要素に挿入：`appendChild()`

## 要素の追加

- `A.appendChild(B)`

B要素を親要素Aの最後に追加します。

```html
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
    <script>
        window.onload = function ()
        {
            var oBtn = document.getElementById("btn");
            //クリックボタンのイベント作成
            oBtn.onclick = function ()
            {
                var oUl = document.getElementById("list");
                var oTxt = document.getElementById("txt");

                // 入力欄の内容でテキストノードを作成
                var textNode = document.createTextNode(oTxt.value);
                // li要素を動的に作成
                var oLi = document.createElement("li");

                //テキストノードをli要素に追加
                oLi.appendChild(textNode);
                //li要素をulに挿入
                oUl.appendChild(oLi);
            };
        }
    </script>
</head>
<body>
    <ul id="list">
        <li>HTML</li>
        <li>CSS</li>
        <li>JavaScript</li>
    </ul>
    <input id="txt" type="text"/><input id="btn" type="button" value="插入" />
</body>
</html>
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3327130/6716aa60-00b2-3b98-4f0a-16e3e47b89af.png)

- `A.insertBefore(B,ref)`

B要素をref(指定子要素)の前に挿入します。A要素が親要素です。
以下のように：

```html
                //oUl.appendChild(oLi);
                oUl.insertBefore(oLi,oUl.firstElementChild);
```

## 要素の削除

-  `A.insertBefore(B,ref)`

`oUl.removeChild(oUl.lastElementChild);`で最後の要素を削除します。

oUlを全部削除するなら、`document.body.removeChild(oUl);`、bodyがoUlの親要素ですので、bodyからoUlを削除します。

## 要素の複製

-  `obj.cloneNode(bool)`
    -  1/true:obj要素及び全ての子要素を複製する
    -  0/false:obj要素のみを複製する

`document.body.appendChild(oUl.cloneNode(1));`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3327130/e246619f-4f1e-1864-126f-263fd180c97b.png)

## 要素の置き換え

`A.replaceChild(new,old);`例えば、以下のJSコード：

```html
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
    <script>
        window.onload = function ()
        {
            var oBtn = document.getElementById("btn");
            oBtn.onclick = function ()
            {
                //获取body中的第一个元素
                var oFirst = document.querySelector("body *:first-child");

                //获取二个文本框
                var oTag = document.getElementById("tag");
                var oTxt = document.getElementById("txt");
                //根据两个文本框的值来创建一个新节点
                var oNewTag = document.createElement(oTag.value);
                var oNewTxt = document.createTextNode(oTxt.value);

                oNewTag.appendChild(oNewTxt);
                document.body.replaceChild(oNewTag, oFirst);
            }
        }
    </script>
</head>
<body>
    <p>JavaScript</p>
    <hr/>
    输入标签：<input id="tag" type="text" /><br />
    输入内容：<input id="txt" type="text" /><br />
    <input id="btn" type="button" value="替换" />
</body>
</html>
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3327130/555ec3e1-2f2c-4cf1-1dfb-b1040dd31833.png)

# 2.DOM中級編

# 参考情報