[JS] DOM（Document Object Model）

DOMとは
---
DOM(Document Object Model)とは
HTMLをJavaScriptから操作できるようにしたインターフェイスです
JavaScriptからはDOM APIを通じてHTMLの情報を取得・変更します
情報の取得・変更・イベントの登録などができます

documentはHTML情報が格納されているオブジェクトです
プロパティ・メソッドを通してHTMLにアクセスして情報を参照・変更したりできます
これがDOM API、もしくはDOM インターフェイスと呼ばれます

取得
---
querySelectorでDOMへアクセスできる

idで指定する

[![Image from Gyazo](https://i.gyazo.com/073c018d3cc51865b3e2d3cbaebfff73.png)](https://gyazo.com/073c018d3cc51865b3e2d3cbaebfff73)

classで指定する
[![Image from Gyazo](https://i.gyazo.com/c633282804dcc49d6e852e63c300ab59.png)](https://gyazo.com/c633282804dcc49d6e852e63c300ab59)

タグで指定する
[![Image from Gyazo](https://i.gyazo.com/9d1e03d98d1701254ff8b5e8ac64be6c.png)](https://gyazo.com/9d1e03d98d1701254ff8b5e8ac64be6c)

例えばliが複数あっても最初の要素のみ取得されます
[![Image from Gyazo](https://i.gyazo.com/5d4dad165de97286831e9764d3f83704.png)]
(https://gyazo.com/5d4dad165de97286831e9764d3f83704)

全てのliを取得したい場合、querySelectorAllを使います
[![Image from Gyazo](https://i.gyazo.com/f9b8e2eb082c50ca868e498506eed22b.png)](https://gyazo.com/f9b8e2eb082c50ca868e498506eed22b)
NodeListは配列に近いオブジェクト

変更
---

[![Image from Gyazo](https://i.gyazo.com/fa23f132afd71ce65cbfa890b08803e7.png)](https://gyazo.com/fa23f132afd71ce65cbfa890b08803e7)
h1の文字列JavaScriptを→　定数h1に代入

[![Image from Gyazo](https://i.gyazo.com/9d17cc88fb08744f48c6ddb9b440134d.png)](https://gyazo.com/9d17cc88fb08744f48c6ddb9b440134d)
JavaScript　→　Arigatoに変更
Arigato　→　Makotoni Arigatoに変更

[![Image from Gyazo](https://i.gyazo.com/cbe8c6c1f1a879ed05817b96ea4e8906.png)](https://gyazo.com/cbe8c6c1f1a879ed05817b96ea4e8906)

[![Image from Gyazo](https://i.gyazo.com/ba8f57f21bc6948f4315687ef50222f0.png)](https://gyazo.com/ba8f57f21bc6948f4315687ef50222f0)

---
classList.addで

[![Image from Gyazo](https://i.gyazo.com/44630108761fd878d8b9c185c74aa2cb.png)](https://gyazo.com/44630108761fd878d8b9c185c74aa2cb)

h1にclass="over"が付与されます
[![Image from Gyazo](https://i.gyazo.com/4b89530cf5d25b44ec83fc49feba6c16.png)](https://gyazo.com/4b89530cf5d25b44ec83fc49feba6c16)

他にも
classList.removeで削除、
classList.toggleで追加したり削除したりできます

---
このようにしてあげるとli要素にstyleを適用できます

[![Image from Gyazo](https://i.gyazo.com/5d1e883c120f6f72bcd4ea3dccf2afef.png)](https://gyazo.com/5d1e883c120f6f72bcd4ea3dccf2afef)

[![Image from Gyazo](https://i.gyazo.com/b88f87fe0be8d985d1486319b57ff419.png)](https://gyazo.com/b88f87fe0be8d985d1486319b57ff419)

forEachで回してあげると全てのli要素にstyleを適用できます
[![Image from Gyazo](https://i.gyazo.com/f18ffff4ec3853cc79fced71dc393ba2.png)](https://gyazo.com/f18ffff4ec3853cc79fced71dc393ba2)

[![Image from Gyazo](https://i.gyazo.com/db8472578cc02c3fcf0a51261374da89.png)](https://gyazo.com/db8472578cc02c3fcf0a51261374da89)

イベント
---
```
const btn = document.querySelector('#btn');
const hello = function() {
  alert('hello');
};

btn.addEventListener('click', hello);
```

[![Image from Gyazo](https://i.gyazo.com/36a916bedf820dcd658d8ab63f292819.png)](https://gyazo.com/36a916bedf820dcd658d8ab63f292819)

---

```
const btn = document.querySelector('#btn');
const hello = function() {
  this.style.color = 'green';
  console.log(this);
};

btn.addEventListener('click', hello);
```

[![Image from Gyazo](https://i.gyazo.com/da7bd78a21f86170ec0eeb794838818b.png)](https://gyazo.com/da7bd78a21f86170ec0eeb794838818b)

thisの中身はこうなっています
[![Image from Gyazo](https://i.gyazo.com/81f9ad81f53c61fc68138b56867a23ab.png)](https://gyazo.com/81f9ad81f53c61fc68138b56867a23ab)

---
addEventListenerでは複数の関数を登録することができます

```
const btn = document.querySelector('#btn');
const h1 = document.querySelector('h1');

function changeColor() {
  h1.style.color = 'green';
};

function changeBgColor() {
  h1.style.backgroundColor = 'yellow';
};

btn.addEventListener('click', changeColor);
btn.addEventListener('click', changeBgColor);
```

[![Image from Gyazo](https://i.gyazo.com/5003a203e06a12425e5013d1311f5f6a.png)](https://gyazo.com/5003a203e06a12425e5013d1311f5f6a)

---

####DOMContentLoaded
HTMLをブラウザが解釈して、DOMツリーを作成し終わったタイミングで発火するイベント

####load
画像・動画・stylesheetなど、全てのコンテンツをダウンロードし終えた時に発火するイベント

---
trimでHTML文の前後のスペースを取り除く

```
document.addEventListener('DOMContentLoaded', function() {
  const el = document.querySelector('.animate-title');
  console.log(el.innerHTML);
});
```

[![Image from Gyazo](https://i.gyazo.com/7e4665c9d731b6f2d8d647907a9b7618.png)](https://gyazo.com/7e4665c9d731b6f2d8d647907a9b7618)

.trimをつけるとこうなる

```
document.addEventListener('DOMContentLoaded', function() {
  const el = document.querySelector('.animate-title');
  console.log(el.innerHTML.trim());
});
```

[![Image from Gyazo](https://i.gyazo.com/4a789535ed86677f503c16623fad9819.png)](https://gyazo.com/4a789535ed86677f503c16623fad9819)

---
文字列にもループが使えるので、このようにfor文で回すと

```
document.addEventListener('DOMContentLoaded', function() {
  const el = document.querySelector('.animate-title');
  const str = el.innerHTML.trim();

  for(let c of str) {
    console.log(`<span class="char">${c}</span>`);
  }
});
```

[![Image from Gyazo](https://i.gyazo.com/925a18373f86211cd8a4aee7ebeb0b42.png)](https://gyazo.com/925a18373f86211cd8a4aee7ebeb0b42)

1文字ずつspan classが付く

replaceメソッド
---
HTMLは半角スペースを無視する仕様なので、
挿入したい場合はreplaceメソッドで半角スペースを＆nbsp;に置換してあげます

```
document.addEventListener('DOMContentLoaded', function() {
  const el = document.querySelector('.animate-title');
  const str = el.innerHTML.trim();
  let concatStr = '';

  for(let c of str) {
    c = c.replace(' ', '&nbsp;');
    concatStr += `<span class="char">${c}</span>`;
  }
  el.innerHTML = concatStr;
});
```

[![Image from Gyazo](https://i.gyazo.com/4e9a43840436f6dee0ca7eda275bc080.png)](https://gyazo.com/4e9a43840436f6dee0ca7eda275bc080)