【JavaScript】DOMの基本

##はじめに
Javascriptを学ぶ上で欠かせない**DOM**について、基礎的な部分を固めたいのでまとめました。
学習サイトやなんやらでJavaScriptの文法的な基礎を学んだ後、次は？みたいな人（わたし）が多いと思います。
そんな方のステップアップに繋がるのがDOMなのかなーと思ってるので、DOM操作に慣れていければいいなと。

##目次
[DOMとは](#DOMとは)
[DOMで何ができるようになるのか](#DOMで何ができるようになるのか)
[要素の取得をする](#要素の取得をする)
[要素取得のメソッド](#要素取得のメソッド)
[要素にアクセスして変更を加える](#要素にアクセスして変更を加える)
[クラスを操作する](#クラスを操作する)


##DOMとは
「**Document Object Model**」の略です。

HTMLは**HTML文章**と呼ばれることもあり、文章=Document。
つまり**HTML(XMLなども)オブジェクトとして扱い、それを操作する**ためのモデルです。
その操作をすることを
**DOM API**　や **DOM** と呼びます。

##DOMで何ができるようになるのか

- JavaScriptを使って**HTMLの情報を取得・変更・イベントの登録**などができる

DOMによって、JavaScriptで動的なページを作ることができるようになるということですね。

##要素の取得をする

Google Chromeの検証モード内のConsole上で確認していきます。
###HTML情報全て取得する

```javascript:JavaScript
document
```
![スクリーンショット 2020-03-31 18.01.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265815/9f0fe9c9-75dc-54c0-2f1f-774b0d52b0cd.png)


コンソールに入力してエンターを押すと、#documentという、HTMLファイル内の情報全てを取得することができます。
![スクリーンショット 2020-03-31 16.42.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265815/e3b282a4-680f-5404-1099-371c76449f71.png)
検証モード内のElementsの内容と一緒です。

###headタグやbodyタグなど

```javascript:JavaScript

document.body
```
と入力することで取得できます。
![スクリーンショット 2020-03-31 18.02.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265815/3430ca22-03e3-3d35-45cf-aeedf177d95d.png)
###bodyタグ内の要素

```javascript:JavaScript
document.body.children
```
![スクリーンショット 2020-03-31 16.53.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265815/efc57e23-551c-81b4-5bd8-f20bb8b464b0.png)

`children`とは子要素のことで、bodyの中の子要素全てを配列のような形(HTMLCollectin)で取得することができます。

##要素取得のメソッド
###querySelector

```javascript:JavaScript
document.querySelector()
```
この`querySelector`メソッドを使用し、HTML内のタグ、id、classなどを指定することでも取得することができます。
![スクリーンショット 2020-03-31 17.59.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265815/d63b1933-69b0-a58c-8866-2e8692846c56.png)
h1タグで取得しても、idで指定しても、同じ要素が取得できます。

ちなみにquerySelectorは、上から探して**最初に見つかった要素ひとつ**を取得するので
![スクリーンショット 2020-03-31 18.08.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265815/f1e17742-6b49-6e09-75c9-ef67f58f58e6.png)
リストが複数あっても、一番上しか取得できていないのが分かりますね。

###querySelectorAll

```javascript:JavaScript
document.querySelectorAll()
```
対して`querySelectorAll`は**指定した要素全て**を取得します。
![スクリーンショット 2020-03-31 18.10.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265815/563c6b15-97ce-f55d-7c6a-6285b9766366.png)
**NodeList**と呼ばれる、配列のような形で取得できます。
ちなみにDOMでは要素のことをnode(ノード)と呼びます。(詳しい説明はここでは割愛)

##要素にアクセスして変更を加える
###innerHTML
`innerHTML`は要素の中身にアクセスすることができます。例えば、h1タグの中身、今回でいうと"DOM操作"という文字列ですね。

```javascript:JavaScript
const h1 = document.querySelector('h1')
h1.innerHTML
```
上のように、取得した要素をいったん変数に入れておくと楽です。
![スクリーンショット 2020-03-31 18.36.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265815/5973eb3f-5c7c-be9c-676b-f286b6a9e88f.png)
これで"DOM操作"という文字列が取得できていることが分かります。

このh1.innerHTMLの中身を書き換えます。

```javascript:JavaScript
h1.innerHTML = '書き換えた'
```
![スクリーンショット 2020-03-31 18.39.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265815/b00f3109-fa6b-e6b3-c483-3437a814ecd6.png)

すると、ブラウザ上の文字列が書き換わります。
また、innerHTMLはタグを認識するので、innerHTML内に＜span＞などを記述してCSSなどを指定することもできます。

```javascript:JavaScript
h1.innerHTML = '書き換えた<span style="color:red">かもね</span>'
```
![スクリーンショット 2020-03-31 18.42.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265815/61051b49-68d8-2941-b13b-7526946ce889.png)

このように、スタイルが適用されます。

###textConetent
`textContent`も要素の中身にアクセスするのですが、こちらはタグなどを無視した**テキスト情報のみにアクセス**します。

```javascript:JavaScript
h1.textContent
```
![スクリーンショット 2020-03-31 18.48.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265815/76ae93b0-7c08-6243-0b8d-1d7c50c68051.png)
spanタグの中身は無視されています。

###style
`style`は文字通り要素のスタイルにアクセスし、変更することができます。

```javascript:JavaScript
const ul = document.querySelector('ul')
ul.style.color = 'green'
```

![スクリーンショット 2020-03-31 20.38.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265815/61a219c0-57d6-dbe5-1dee-f52c098d3cfd.png)

ulのstyleを変更してみました。

##複数要素を取得した場合
querySelectorAllで要素全てを取得した場合のアクセス方法

###添字指定
```javascript:JavaScript
const li = document.querySelectorAll('li')
li[1].style.textDecoration = 'underline'
```
上記のようにtext-decorationの指定などはプロパティ名がそのまま使えないものがあるので注意しましょう。

![スクリーンショット 2020-03-31 20.51.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265815/e22b380e-b066-175b-e9e2-fdf847cd3602.png)

配列に格納されているので、添字を指定することでアクセスできました。

###ループ文
複数要素全てにアクセスするには、ループ文が有効です。

```javascript:JavaScript
li.forEach(node => node.style.color = 'purple')
```
querySelectorAllで取得してきた場合は、NodeListに格納されるので、そのひとつ(node)ずつにアクセスすればよいです。
![スクリーンショット 2020-03-31 21.07.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265815/70959214-da97-435e-47f6-bfe9cb35dd60.png)
これでli要素全てに適用できました。

##クラスを操作する
要素の変更のほかに、ノードに対するクラス情報も取得してそれらを操作することができます。

###classList
`classList`にアクセスし、その要素のクラス情報を取得します。
`add`メソッドでクラスを追加することができます。

```javascript:JavaScript
const h1 = document.querySelector('#title')
h1.classList.add('text-size')
```
![スクリーンショット 2020-03-31 21.23.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265815/a2dd5b67-b0bb-a212-0365-5a376395cd0d.png)
![スクリーンショット 2020-03-31 21.24.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265815/42490dd5-40b0-53b4-30bf-e253fe21c43a.png)
elementsを確認すると、h1タグの中にtext-sizeというクラスが追加されています。

もちろんこの新しく付与されたクラスにプロパティが指定してあればそれが適用されます。
![スクリーンショット 2020-03-31 21.28.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265815/1c7d2466-0379-cbc4-57a8-2d1dc28d90e4.png)

また`remove`メソッドを用いることで、クラスを除去したり
`toggle`メソッドではそれが呼ばれるたびにクラスを追加したり除去したりといったことができるようになります。