JavaScript入門 その6：DOM操作

JavaScript入門の書籍を読んで書いてあったこと＋自分で調べたことのメモ書きその5。DOM操作


# DOM
DOM（Document Object Model）とはWEBページのデータ表現である。
JavaScriptを使ってDocumentオブジェクトが持つDOMツリーを変更することによってWEBページの内容を操作することができる。

#### Windowオブジェクト
Webブラウザのウィンドウそのものを表すオブジェクト。
Documentオブジェクト、Consoleオブジェクトをプロパティとして持つ。
Windowオブジェクトはプログラムの中で省略できる。

```js
window.console.log("a");
console.log("b");
```

【実行結果】
```console
a
b
```

#### Documentオブジェクト
Webページの内容全体を表すオブジェクト。
Webページの内容をElementオブジェクトを要素とする木構造であるDOMツリーとして持っている。

#### Consoleオブジェクト
コンソールを表すオブジェクト。
今まで頻繁に出てきた `console.log` はコンソールオブジェクトのメソッド log である。

#### Elementオブジェクト
Webページ内の要素（テキスト、ボタンなど）を表すオブジェクト。


### 要素の選択

#### Document:getElementById(id)
id属性で要素を取得する。
戻り値はElementオブジェクト。該当する要素がない場合はnull。

#### Document:querySelector(selector)
セレクターで要素を取得する。カンマで複数指定が可能（OR条件になる）。最初に一致した要素を返す。
戻り値はElementオブジェクト。該当する要素がない場合はnull。

#### Document:querySelectorAll(selector)
セレクターで要素を取得する。カンマで複数指定が可能（OR条件になる）。一致する要素すべてを返す。
戻り値は一致した要素をElementオブジェクトを含むNodeList。該当するものがなければ空のNodeList。

```js
let elementList = document.querySelectorAll("li");
for (let element of elementList) {
  console.log(element.innerText);
}
```

`element` は `HTMLElement`オブジェクトで、`Element`を実装している。`innerText`は`HTMLElement`のプロパティである。


### 要素の追加・削除

#### Document.createElement(tagName)
タグ名を指定して新しい要素を作成する。
戻り値はElementオブジェクト。

#### Node.appendChild(child)
子要素の末尾に要素を追加する。
`Node` は`Element`、`Document`の親クラス。

```js
let newElement = document.createElement("p");
newElement.innerText = "新たな要素";
document.body.appendChild(newElement);
```

#### Node:insertBefore(element, referenceElement)
引数`newElement`を`referenceElement`の前に追加する。
`parent.insertBefore(element, referenceElement)` とした場合、`parent` は `referenceElement` の親要素でなければならない。

```js
let parent = document.querySelector("div.block");
let textArea = document.querySelector("textarea");
let newElement = document.createElement("p");
newElement.innerText = "新たな要素";
parent.insertBefore(newElement, textArea);
```

#### Element:remove()
要素を削除する。

```js
let element = document.getElementById("text");
element.remove();
```

#### Node:removeChild(child)
指定した子要素を削除する。
`parent.removeChild(element)`として場合、`parent` は `element` の親要素でなければならない。
削除されている要素はDOMの一部ではなくなるが、どこかから参照されている限りメモリー内に残り、後のコードで再利用することがでる。参照されなくなればメモリから自動的に削除される。

```js
let parent = document.querySelector("div.block");
let textArea = document.querySelector("textarea");
parent.removeChild(textArea);
```


### イベントの設定

#### イベントの種類
マウス操作関連

| イベントタイプ名 | 発生するタイミング |
|:-|:-|
| mouseover | 要素の上にマウスポインタが当たった |
| mouseout | 要素の上からマウスポインタが外れた |
| mousedown | 要素の上でマウスボタンを押下した |
| mouseup | 要素の上でマウスボタンを離した |
| click | 要素をクリックした |
| dblclick | 要素をダブルクリックした |
| mousemove | 要素の上でマウスを動かした |

キーボード操作関連

| イベントタイプ名 | 発生するタイミング |
|:-|:-|
| keydown | キーを押下した |
| keyup | キーを離した |

その他

| イベントタイプ名 | 発生するタイミング |
|:-|:-|
| focus | フォーカスが当たった |
| blur | フォーカスが外れた |
| load | 読み込みが完了した |
| unload | アンロードが行われた<br>（ページ遷移した時など） |
| submit | フォームが送信された |

#### EventTarget:addEventListener(type, listener)
指定したタイプのイベントのイベントリスナーに追加する。
`EventTarget`は`Element`など。

例：要素にマウスポインタ乗ったらテキストを変更する。
```js
let target = document.getElementById("text");
target.addEventListener("mouseover", () => {
  target.innerText = "いいい";
});
```

例：input要素に入力された値を取得する。
```js
let input = document.querySelector("input");
input.addEventListener("keyup", () => {
  let value = input.value;
  let element = document.getElementById("text");
  element.innerText = value;
});
```

例：セレクタで取得した複数の要素について、クリックされたらクラスを変更する。
```js
for (let element of document.querySelectorAll("p")) {
  element.addEventListener("click", function (e) {
    e.currentTarget.className = "bg-blue";
  });
}
```

# 参考情報

### 書籍
[解きながら学ぶJavaScriptつみあげトレーニングブック | マイナビブックス](https://book.mynavi.jp/ec/products/detail/id=126984 "解きながら学ぶ JavaScriptつみあげトレーニングブック | マイナビブックス") 8章

### WEBページ
[DOM の紹介 - Web API | MDN](https://developer.mozilla.org/ja/docs/Web/API/Document_Object_Model/Introduction)
[Node - Web API | MDN](https://developer.mozilla.org/ja/docs/Web/API/Node)
[Document - Web API | MDN](https://developer.mozilla.org/ja/docs/Web/API/Document)
[Element - Web API | MDN](https://developer.mozilla.org/ja/docs/Web/API/Element)
[HTMLElement - Web API | MDN](https://developer.mozilla.org/ja/docs/Web/API/HTMLElement)
[EventTarget - Web API | MDN](https://developer.mozilla.org/ja/docs/Web/API/EventTarget)
[Event - Web API | MDN](https://developer.mozilla.org/ja/docs/Web/API/Event)