JS初心者によるJS初心者のためのDOM入門

初めまして, javascript歴一週間のyasudadesuです(html, css歴は1日)。

ひょんなことからjsを触ることになったのですが普段(python)との違いにとても戸惑った(今もなお戸惑っていますが)ので,それをメモとして残しておこうと思います。
対象は本当の本当にjsを知らない人としておりますので,もし間違っているところやもう少し理解しやすい方法がありましたらコメントにて教えていただければと思います。
また,今回の内容はw3schoolsを大変参考にさせていただきました。

## DOMとは
- Document Object Modelのこと
- htmlなどの文書の\<p>などにアクセスする仕組み
- W3Dにより3つに分けて各文書に対応している
    - Core DOM: 全ての文書のタイプに対応
    - XML DOM: XML文書に対応
    - HTML DOM: HTML文書に対応

<img width="653" alt="スクリーンショット 2018-07-02 15.56.19.png" src="https://qiita-image-store.s3.amazonaws.com/0/190157/d9013046-a1ab-9b80-7a86-50e26d42cfa7.png">
(参考: [w3 school - Javascript HTML DOM](https://www.w3schools.com/js/js_htmldom.asp))

ここでは, 簡単のためDOMとのみ書いた場合HTML DOMを指すことにします。

### **HTML DOMとは？**
- HTMLの各要素をどうやって取得(get),変更(change),追加(add),削除(delete)するのかの標準化したもの


## JSとDOMでできること
- DOMを使うことで, JSはHTMLドキュメントの全ての要素にアクセスし,値を変更することができる
- **JSという言語自体はDOMとは無関係で, ブラウザがよしなにレンダリングしてくれている**
    - jsから何の宣言もなく`document`や`window`を呼び出せるのもこれによる


### **JS scriptによるアクセスの一例**

- `getElementById(id)`を使用します。
    - idはhtmlの中で一意なので,このメソッドの引数にidを指定することで中身を取得することができます。
    - また, 例コードのようにすることで変更することもできます。

#### htmlのみで書く場合
```html:index.html
<!DOCTYPE html>
<html>
<body>

<p id="demo"></p>
<script>
    document.getElementById("demo").innerHTML = "Hello World!";
</script>

</body>
</html>
```

#### htmlとjsを別々で書く場合
```html:index.html
<!DOCTYPE html>
<html>
<body>

<p id="demo"></p>
<script src="index.js"></script>

</body>
</html>
```

```javascript:index.js
document.getElementById("demo").innerHTML = "Hello World!";
```

### **HTMLからJSの関数を呼び出す**
参考: [JavaScript HTML DOM Animation](https://www.w3schools.com/js/js_htmldom_animate.asp)


```html:index.html
<!DOCTYPE html>
<html>
<head>
  <style>
    #container {
      width: 400px;
      height: 400px;
      position: relative;
      background: yellow;
    }
    #animate {
      width: 50px;
      height: 50px;
      position: absolute;
      background-color: red;
    }
  </style>
</head>
<body>
  <!-- クリックされた時に関数を実行するようにしている -->
  <p><button onclick="myMove()">Click Me!</button></p>
  <div id="container">
    <div id="animate"></div>
  </div>
  <script src="index.js"></script>
</body>
</html>
```

```javascript:index.js
function myMove() {
    let animeElement = document.getElementById("animate");
    let pos = 0;
    let id = setInterval(frame, 5);  // 一定時間ごとに特定の処理を繰り返す
    function frame() {
        if (pos==350) {
            clearInterval(id);  // setIntervalの処理を停止する
        } else {
            pos++;
            animeElement.style.top = pos+'px';
            animeElement.style.left = pos+'px';
        }
    }
}
```

### **Eventに反応する**
#### Eventとは
- ユーザーが『クリックした』, 『マウスカーソルを乗せた』などの行いのこと

#### Event Handlerとは
- イベントが起こった時の動作を定義しているもの
- つまり例えば,『ユーザーがクリックした時に`hoge`というメソッドを実行する』ためのもの

#### eventの取得例
- onmouseover ... 要素にマウスが乗っている時
- onmouseout ... 要素にマウスが乗っていない時
- onmousedown ... 要素をクリックしている時
- onmouseup ... 要素をクリックしていない時
- 他にもonload, onfocusなどもある

#### event_handlerの例
```html:eventHandler1.html
<!DOCTYPE html>
<html>
<head></head>
<body>
  <!-- クリックされた時にchangeTextという関数を呼ぶように設定している -->
  <h1 onclick="changeText(this)">Click on this text!</h1>
  <script src="index.js"></script>
</body>
</html>
```

```html:eventHandler2.html
<!DOCTYPE html>
<html>
<head>
  <style>
    #mEvent {
      background-color: #D94A38;
      width: 120px;
      height: 20px;
      padding: 40px;
    }
  </style>
</head>
<body>
  <div id="mEvent" onmouseover="mOver(this)" onmouseout="mOut(this)">
    Mouse Over Me!
  </div>
  <!-- このスクリプトにmOutとmOverを書く -->
  <script src="index.js"></script>
</body>
</html>
```

### **addEventListener()**
- カスタムのイベントを作ることができるわけではない
- 既存のイベントハンドラーを上書きすることなく,あるイベントハンドラをある要素にアタッチできる
- 文法は`element.addEventListener(event, function, useCapture)`
    - 一つ目は 'click'やら'mousedown'やら
    - ２つ目はイベントが起こったときに実行したい関数
    - ３つ目はブーリアン(詳細は[JavaScript HTML DOM EventListener](https://www.w3schools.com/js/js_htmldom_eventlistener.asp)参照)

```html:index.html
<!DOCTYPE html>
<html>
<head></head>
<body>
  <button id="myBtn">Try</button>
  <p id="demo"></p>
  <script src="index.js"></script>
</body>
</html>
```

```javascript:index.js
let p1 = 5;
let p2 = 7;

document.getElementById("myBtn").addEventListener("click", function() {
    myFunction(p1, p2)
});

function myFunction(a, b) {
    const result = a * b;
    document.getElementById("demo").innerHTML = result;
}
```

## 参考
- [w3 school - Javascript HTML DOM](https://www.w3schools.com/js/js_htmldom.asp)