【JavaScript】JavaScriptまとめ⑧（イベント）

# 概要
JavaScriptの理解を深めるため、
[<img width="200" alt="51vlB3JskRL.jpg" src="https://m.media-amazon.com/images/I/41vZUGXaYML._SX350_BO1,204,203,200_.jpg">](https://www.amazon.co.jp/%E3%82%B9%E3%83%A9%E3%82%B9%E3%83%A9%E3%82%8F%E3%81%8B%E3%82%8BJavaScript-%E6%96%B0%E7%89%88-%E6%A1%9C%E5%BA%AD-%E6%B4%8B%E4%B9%8B/dp/4798173266/ref=sr_1_15?crid=341O9294X80Z7&keywords=javascript&qid=1679238835&sprefix=javas%2Caps%2C185&sr=8-15)
で学習した内容を記載していく。

本記事では、イベントについて記載する。

## イベント
### イベントとは
プログラミングにおける`イベント`とは、システム内で発生した何らかの出来事をシステムに知らせるという仕組み。

### イベントを使う
#### イベントを設定する
イベントの仕組みを使うには、特定の要素に対してイベントを設定する必要がある。イベントの設定には`addEventListener()`を使う。
```
要素.addEventListener(イベント名, 関数名);
```
```add_event.html
<!DOCTYPE>
<html>
    <head>
        <meta chaset="UTF-8">
    </head>
    <body>
        <button type="button">ボタン</button>
        <script>
            function alertMessage() {
                alert('ボタンをクリックしました');
            }
        
            const button = document.querySelector('button');
            button.addEventListener('click', alertMassage);
        </script>
    </body>
</html>
```
まずはアラートを表示する関数alertMessage()を定義する。次に、ボタンクリックのイベント設定をaddEventListener()で行う。第一引数にはクリックイベントを表す`click`を渡す。そして、第二引数には関数名を渡す。
#### 関数式を渡す方法
関数名を渡す以外に、関数式を渡すこともできる。
```
const button = document.querySelector('button');
button.addEventListener('click', function() {
    alert('ボタンをクリックしました');
});
```
### 様々なイベント
#### クリックイベント
`click`イベントは要素のクリック時に発生する。
```click_event.html
<!DOCTYPE>
<html>
    <head>
        <meta chaset="UTF-8">
    </head>
    <body>
        <button type="button">ボタン</button>
        <script>
            const button = document.querySelector('button');
            button.addEventListener('click', function() {
                console.log('クリックしました');
            });
        </script>
    </body>
</html>
```
#### inputイベント
`input`イベントはフォームの入力欄にデータが入力されたときに発生する。
```input_event.html
<!DOCTYPE>
<html>
    <head>
        <meta chaset="UTF-8">
    </head>
    <body>
        <input type="text">
        <script>
            const input = document.querySelector('input');
            input.addEventListener('input', function(event) {
                const value = event.currentTarget.value;
                console.log(`入力内容: ${value}`);
            });
        </script>
    </body>
</html>
```   
#### keydown/keyupイベント
`keydown`はキーを押したとき、`keyup`はキーを押してから離したときに発生する。引数のイベントオブジェクトの`key`プロパティに押下されたキーの種類が格納されている。
普通の英数字だけでなくコントロールキーやシフトキーなど特殊なキーの入力も判断することができる。     
```key_event.html
<!DOCTYPE>
<html>
    <head>
        <meta chaset="UTF-8">
    </head>
    <body>
        <input type="text">
        <script>
            const input = document.querySelector('input');
            input.addEventListener('keydown', function(event) {
                console.log(event.key);
            });
        </script>
    </body>
</html>
```
#### mousemove/mousedown/mouseupイベント
`mousemove`はマウスを動かしたときにイベントが発生する。イベントオブジェクトの`offsetX`と`offsetY`プロパティで画面左上を始点とした座標データを取得することができる。`mousedown`はマウスのボタンを押下したとき、`mouseup`は押下して離したとき発生する。  
```mouse_event.html
<!DOCTYPE>
<html>
    <head>
        <meta chaset="UTF-8">
    </head>
    <body>
        <div style="width: 200px; height: 100px; background: pink;"></div>
        <script>
            const div = document.querySelector('div');
            div.addEventListener('mousemove', function(event) {
                console.log(`Move : x = ${event.offsetX}, 
y = ${event.offsetY}`);
            });
            div.addEventListener('mousedown', function(event) {
                console.log(`Down : x = ${event.offsetX}, 
y = ${event.offsetY}`);
            });
            div.addEventListener('mouseup', function(event) {
                console.log(`Up : x = ${event.offsetX}, 
y = ${event.offsetY}`);
            });
        </script>
    </body>
</html>
```
#### scrollイベント
スクロールをするたびにイベントが発生する。また、画面全体に関することなのでwindowオブジェクトにaddEventListener()でイベントを設定する。スクロール量は`window.scrollY`プロパティで取得することができる。
```scroll_event.html
<!DOCTYPE>
<html>
    <head>
        <meta chaset="UTF-8">
    </head>
    <body>
        <div class="scroll"></div>
        <script>
            const scrollContent = document.querySelector('.scroll');
            for(let i = 0; i < 1000; i++ {
                scrollContent.textContent += ` テキスト ${i} `;
            }
            window.addEventListener('scroll', function() {
                console.log(`スクロール量は${window.scrollY} pxです`);
            });
        </script>
    </body>
</html>
```

### イベント発生元の要素にアクセスする
#### イベントオブジェクトについて
`イベントオブジェクト`とは、あらかじめ登録しておいた関数に引数として自動で渡される、特別なオブジェクトである。
イベントオブジェクトの受け取り方は、addEventListener()に登録する関数に引数を渡すだけ。
```
button.addEventListener('click', function (event) {
    // eventがイベントオブジェクト
    console.log(event);
});
```
#### イベントが発生した要素を取得する
```target_event.html
<!DOCTYPE>
<html>
    <head>
        <meta chaset="UTF-8">
    </head>
    <body>
        <button type="button">ボタン</button>
        <script>
            const button = document.querySelector('button');
            button.addEventListener('click', function(event) {
                const button = event.currentTarget;
                button.textContent = '変更します';
            });
        </script>
    </body>
</html>
```
イベントオブジェクトの`currentTarget`プロパティにはイベントが発生した要素が格納されている。
#### currentTargetとtargetの違い
currentTargetと似たプロパティで`target`というものがある。違いは以下の通り。

・<INS>**`currentTarget` : addEventListenerを設定した要素**
・<INS>**`target` :　設定したイベントが発生した要素**
```target.html
<!DOCTYPE>
<html>
    <head>
        <meta chaset="UTF-8">
    </head>
    <body>
        <button type="button">
            <span>span要素です</span>
            ボタン要素です
        </button>
        <script>
            const button = document.querySelector('button');
            button.addEventListener('click', function(event) {
                console.log(event.currentTarget);
                console.log(event.target);
            });
        </script>
    </body>
</html>
```
ボタン要素の中に`<span>`要素を入れている。ボタン全体に対してクリックイベントを設定しているので、ボタンのどこをクリックしてもイベントが発生する。しかし、`<span>`で囲まれた部分をクリックする場合は、`<span>`要素でクリックイベントが発生していることになる。
つまり、`<span>`部分をクリックすると`currentTarget`には`<button>`が、`target`には`<span>`要素が格納される。
#### 規定の動作を停止する
イベントオブジェクトの`preventDefault()`を使うと、規定の動作を停止することができる。
規定の動作を停止するには、イベント発生時に受け渡されるイベントオブジェクトに対してpreventDefault()メソッドを実行するだけ。
```
イベントオブジェクト.preventDefault();
```
リンクをクリックした際に「本当にページ遷移しますか？」と確認をとり、OKならそのままページ遷移、キャンセルした場合はページ遷移を停止するようにしてみる。
```prevent_event.html
<!DOCTYPE>
<html>
    <head>
        <meta chaset="UTF-8">
    </head>
    <body>
        <a href="https://example.com">リンク</a>
        <script>
            function confirmLink(event) {
                if (confirm('ページ遷移しますか?')) {
                    console.log('実行しました');
                } else {
                    event.preventDefault();
                    console.log('キャンセルしました');
                }
            }

            const link = document.querySelector('a');
            button.addEventListener('click', confirmLink);
            });
        </script>
    </body>
</html>
```
`<a>`要素のclickイベント時に`confirm()`関数を使って、ユーザーに確認するダイアログを表示する。
「キャンセル」を選択するとpreventDefault()が実行され`<a>`要素のページ遷移動作を停止することができる。