DOMイベント入門 [JavaScript]

DOMの中でも、DOMイベントについてまとめていきたいと思います。

イベントを使うことで、

・ユーザーがクリックしたとき
・ホバーしたとき
・ドラックしたとき
・サブミットしたときなどに特定の処理を行えるようになります。

つまり、

:::note info
**ユーザーが行ったアクションに対して反応する**
ために欠かせないのが、DOMイベントになります。
:::
DOMイベント自体は大量に種類があるので、
今回はDOMイベントの書き方に絞ってまとめていこうと思います。

## 目次：

- [1. イベントの書き方(インラインイベント)](#1-イベントの書き方インラインイベント)
- [2.イベントの書き方(JavaScriptファイルから定義する)](#2-イベントの書き方javascriptファイルから定義する)
- [3. イベントの書き方(addEventListenerを使った書き方)](#3-addeventlistenerを使った書き方)

## 1. イベントの書き方(インラインイベント)

イベントを書く方法は主に３種類あります。
それぞれ説明していきます。

#### 1-1. インラインイベント

インラインイベントとは、HTMLにイベントの内容を直接書き込む書き方です。
この書き方は、コードを読みにくくする性質があるため、一般に推奨されていない書き方となります。

例：
HTMLの中に、h1とボタンを作成します。
このボタンがクリックされたときに、イベントを発火するようにインラインイベントを設定してみたいと思います。

```html
<body>
    <h1>DOMイベント</h1>
    <button onclick="alart('クリックした！')">クリックする！</button>

</body>
```

1. buttonの要素の中に直接domイベントを記載します。
2. 今回は、onclick属性を設定し、中身にJavaScriptでalartを設定します。
alartの中身として、クリックされたときに、「クリックした！」という文章が表示されます。  
<img src= https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3679750/f17261e9-a092-d670-d5e7-3b5e0b610aa6.png>

これで、ボタンをクリックされたときに、DOMイベントを発火させるという目的は達成できるのですが、
この書き方にはいくつか欠点がある為、推奨される書き方ではありません。

#### 1-2. インラインイベントの欠点

・HTMLが読みづらくなる。

今回は、alartを一つ入れただけだったので、複雑な見た目にはなっていませんが、
複数のロジックをこの中に入れる場合、コードの可読性が下がり、見た目に複雑さが増してしまいます。

・複数の同じ処理を実装しにくい。

DOMイベントで、「〜をしたら〜を実行する」というイベントの内容を複数の箇所で実装したい場合は多々あります。
その際に、先に書いた内容を複数の場所に同じように書いてしまうと、コードの可読性が下がり、修正や変更の加えにくいコードとなってしまいます。

## 2. イベントの書き方(JavaScriptファイルから定義する)

JavaScriptファイルから関数を定義することにより、DOMイベントを使用することができます。

例：
先ほどのインラインイベントの時に使用したHTMLファイルを修正して再利用します。
1. h1にタイトルを記載
2. buttonは、v2としてidを設定。JavaScriptファイルから読み込み使用します。
3. scriptでJavaScriptファイルと接続します。(JavaScripファイルの名前はapp.jsとします。)  
```html
<body>
    <h1>DOMイベント</h1>
    <button onclick="alert('クリックした！')">クリックする！</button>
    
    <button id ="v2">クリックしたv２！</button>

<script src = "app.js"></script>
</body>
```
JavaScriptファイル記載内容
1. HTMLのid属性#v2を取得し、btnという変数として保存
2. btnがクリックされたときの関数を記載。 
```js
const btn = document.querySelector('#v2');

btn.onclick = function() {
    console.log('クリックしたv2!')
}

```
クリックするv2!ボタンをクリックすると、console.logのクリックしたv2!が出力されているのを確認できます。
```text:出力結果：
クリックしたv2！
```
<img src = https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3679750/785e0951-1937-7332-9e82-e6d2c336e89c.png>

#### 2-2. JavaScriptファイルから定義する欠点

・複数のイベントを同時に定義することが困難

・addEventListenerの方が、オプションを渡すことで、より柔軟なイベントを発火することができる。
（addEventListenerは、次の３つ目の書き方として後述します。）

## 3. addEventListenerを使った書き方

#### 3-1. addEventListenerを使用した書き方
が、DOMイベントを書く際には一番使いやすくかつ応用の効く書き方になります。

JavaScriptファイルに記載します。
具体的な書き方としては、
1. DOMで要素の取得
2. 1で取得した要素に対してaddEventListenerというメソッドを呼ぶ
2-1. 第一引数に、反応したいイベントの名前を書きます。
2-2. 第二引数に、イベントが起きた時の反応の内容を書きます。
2-3. 第三匹数としてオプションを渡すことも可能です。

例：
先ほどの2.JavaScriptファイルから関数を定義する時に使用したHTMLファイルを修正して再利用します。

・ buttonは、v3としてidを設定。JavaScriptファイルから読み込み使用します。

```html
<body>
    <h1>DOMイベント</h1>
    <button onclick="alert('クリックした！')">クリックする！</button>
    
    <button id ="v2">クリックしたv２！</button>
    
    <button id ="v3">クリックしたv3！</button>

<script src = "app.js"></script>
</body>
```
JavaScriptファイル記載内容
1. HTMLのid属性#v3を取得し、btn3という変数として保存
2. btn3がクリックされたときのイベントを記載
2-1. イベントを発動させる要素に対してメソッドaddEventListenerを書きます。
2-2. 第一引数 - 発動させたいイベント名（今回は、click）
2-3. 第二引数 - イベントの実行したい処理内容(今回は、alertでクリック！と出力します。)
2-4. 第三匹数 - オプションを渡すことができます。
```js
const btn3 = document.querySelector('#v3');

btn3.addEventListener('click',function(){
    alert('クリック！')
})
```
クリックする2!ボタンをクリックすると、console.logのクリックしたv2!が出力されているのを確認できます。
```text:出力結果：
クリックしたv2！
```

また、発動させたいイベントは複数存在するため、MDNのイベントリファレンスを参照いただけますと幸いです。

>[MDN イベントリファレンス参照：](https://developer.mozilla.org/ja/docs/Web/Events)

#### 3-2. addEventListenerを使用する利点

・ 同じイベントに複数の処理を割り当てることができます。

例：JavaScriptの関数定義でDOMイベントを発動する場合

HTMLで作成したbutton4に対して、クリックのDOMイベントを行います。
クリックしたらclick1とclick2を出力する関数が発動します。

```html
<button id="v4">クリックするv4！</button>
```

```js

function click1() {
    console.log('クリック１');
}

function click2() {
    console.log('クリック2');
}

const btn4 = document.querySelector('#v4');

btn4.onclick = click1;
btn4.onclick = click2;
```

```text:出力結果：
クリック2
```

しかし、関数を定義するDOMイベントの場合、click1は、click2に上書きされてしまい、
click2しか出力されません。

このような場面で、addEventListenerは有効に働きます。

例：addEventListenerを使用してDOMイベントを発動させる場合。


```html
<button id="v4">クリックするv4！</button>
```

```js

function click1() {
    console.log('クリック１');
}

function click2() {
    console.log('クリック2');
}

const btn4 = document.querySelector('#v4');

btn4.addEventListener('click',click1);
btn4.addEventListener('click',click2);

```
addEventListenerの効果で、click1とclick2の関数の２つの要素をbtn4に付与することができています。

```text:出力結果：
クリック1
クリック2
```

btn4に対して、addEventListenerをします。
第一引数として、発火させるイベントの名前（click）
第二引数として、発動させる処理の内容（click1）、(click2)
をそれぞれ記載することにより、2つの処理をもつDOMイベントを作成することができます。


#### 3-3. オプションを渡してより詳細なイベントを作成することができる。

addEventListenerでは、第三匹数にオプションを渡すことにより、様々な挙動を変更することができます。

https://developer.mozilla.org/ja/docs/Web/API/EventTarget/addEventListener#:~:text=%E3%81%A6%E3%81%8F%E3%81%A0%E3%81%95%E3%81%84%E3%80%82-,options,-%E7%9C%81%E7%95%A5%E5%8F%AF

例： onceオプションを使ってみる

先ほどの、ボタンv4を使用してonceオプションを使用してみたいと思います。

onceオプションは、指定されているロジックを１回表示させるようにするためのオプションになります。

```html
<button id="v4">クリックするv4！</button>
```

addEventListenerの第三匹数として、onceをtureに設定します。

```js

function click1() {
    console.log('クリック１');
}

function click2() {
    console.log('クリック2');
}

const btn4 = document.querySelector('#v4');

btn4.addEventListener('click',click1,{once: true});
btn4.addEventListener('click',click2,{once: true});

```
btn4をクリックすると、クリック1とクリック2が表示されますが、
onceオプションを渡すことにより、一度しかイベントが発火されなくなります。

```text:出力結果：
クリック1
クリック2
```