更新日:
【JavaScript】 addEventListenerメソッドについて徹底解説!
addEventListenerメソッドは、Webページ上の要素で起こるイベントを検知し、それに応じた処理を実行するためのメソッドです。
イベントリスナーとは
イベントリスナーはWebページ上の特定の要素(ボタンやリンク、フォームなど)に対して、ユーザーが特定の操作(クリック、マウスオーバー、キーボード入力など)を行ったときに、その操作を検知して指定された処理を実行するための仕組みです。
イベントリスナーを使用することで、ボタンをクリックしたときにモーダルを表示したり、スライドをクリックして横にスライドさせたりといったようなことができるようになります。
イベントリスナーの使い方
イベントリスナーを使うには、addEventListener()
メソッドを使用します。このメソッドは特定の要素に対して呼び出します。
1
要素.addEventListener(`event`, listener, options)
各引数は以下のように指定します。
- event: イベントの種類
- listener: イベント発生時に実行される関数
- options: オプション設定(省略可能)
例えば、ボタンをクリックしたときに、アラートを表示するイベントリスナーを追加する場合は、以下のようになります。
1
<button id="myButton">クリックしてね</button>
1
2
3
4
5
const button = document.getElementById('myButton');
button.addEventListener('click', function() {
alert('ボタンがクリックされました!');
});
この例ではまずgetElementById
メソッドを使ってHTMLのソースの中からmyButton
というidが付与されている要素を取得します。次に、その要素に対しaddEventListener
を使い、クリックイベントのイベントリスナーを追加します。イベント発生時に実行される関数では「ボタンがクリックされました!」というアラートを表示する処理を記述しています。
今回の例では、取得したボタン要素に対してクリックイベントが発生したかどうかを検知するリスナーを追加しました。リスナーは、その名前が示すように「耳を澄ませる」ようなイメージでイベントの発生を常に監視し、必要な処理を実行します。
イベントとは
イベントとはWebページ上で発生する出来事です。
例えばクリックした時やマウスオーバーされた時、キーボードのキーが押された時などさまざまな状況があります。
先ほどの例はクリックイベントになります。
実際の活用例
この章ではイベントリスナーの活用例を紹介します。
ボタンがクリックされた時
ボタンがクリックされたときにアラートを出す例です。
1
<button id="myButton">クリックしてね</button>
1
2
3
4
5
const button = document.getElementById('myButton');
button.addEventListener('click', () => {
alert('ボタンがクリックされました!');
});
ボタンがクリックされた場合の処理の順番を以下に記述します。
myButton
のidを持つ要素を取得- 取得した要素に、クリックされた場合のイベントリスナーを設定
- ユーザーがボタンをクリック
- クリックイベントの中身の処理が実行
1. myButtonのidをもつ要素を取得
1
2
3
4
5
const button = document.getElementById('myButton');
button.addEventListener('click', () => {
alert('ボタンがクリックされました!');
});
document.getElementById
メソッドは、指定したidの要素を取得するメソッドです。今回は、myButton
というidを持つ要素を取得しています。
2. 取得した要素に、クリックされた場合のイベントリスナーを設定
1
2
3
4
5
const button = document.getElementById('myButton');
button.addEventListener('click', () => {
alert('ボタンがクリックされました!');
});
続いてボタンがクリックされたときに処理されるイベントリスナーを設定します。イベントリスナーを設定するには、addEventListerner
を使います。そして要素.addEventListener
と書くことによって対象の要素になんらかの操作が実行された後に、どのような処理をするかを設定できます。今回はclick
を第一引数に設定しているので、button
がクリックされた後の処理を設定しています。
3. ユーザーがボタンをクリック
ユーザーがブラウザに表示されている「クリックしてね」と書かれたボタンをクリックします。
4. クリックイベントの中身の処理が実行
1
2
3
4
5
const button = document.getElementById('myButton');
button.addEventListener('click', () => {
alert('ボタンがクリックされました!');
});
3でユーザーがクリックしたことによって、click
イベントの中身のalert
が実行されます。
このようにまずはイベントリスナーを追加するための要素を取得することから始めるのが重要です。
下のボタンをクリックして実際にアラートが出るか確認してみましょう。
See the Pen eventlistner_click by miyajima yuya (@pikawaka) on CodePen.
文字が入力された時
入力欄に文字を入力する際、キーボードのキーを押したときにアラートを出す例です。
1
<input type="text" id="myInput" placeholder="入力してみてください">
1
2
3
4
5
const input = document.getElementById('myInput');
input.addEventListener('keydown', (event) => {
alert(`${event.key}のキーが押されました`);
});
文字が入力された場合の処理を以下に記述します。
myInput
のidを持つ要素を取得- 取得した要素に、キーボードのキーが押された場合のイベントリスナーを設定
- ユーザーがキーボードのキーを押す
keydown
イベントの中身の処理が実行
1. myInputのidを持つ要素を取得
1
2
3
4
5
const input = document.getElementById('myInput');
input.addEventListener('keydown', (event) => {
alert(`${event.key}のキーが押されました`);
});
この例もまずdocument.getElementById('myInput')
で文字が入力されるinput
要素を取得します。
2. 取得した要素に、キーボードのキーが押された場合のイベントリスナーを設定
1
2
3
4
5
const input = document.getElementById('myInput');
input.addEventListener('keydown', (event) => {
alert(`${event.key}のキーが押されました`);
});
次に、取得した要素に対してaddEventListener
を使用します。キーボードのキーが押された時に発火させたいのでkeydown
イベントを指定しています。
3. ユーザーがキーボードのキーを押す
ユーザーがブラウザに表示されているインプット欄に何か文字を入力します。
4. keydownイベントの中身の処理が実行
1
2
3
4
5
const input = document.getElementById('myInput');
input.addEventListener('keydown', (event) => {
alert(`${event.key}のキーが押されました`);
});
3でユーザーがキーボードのキーを押したことによってkeydown
イベントの中身のalert
が実行されます。今回はイベントオブジェクトにkeyプロパティ
を使うことで実際に押されたキーの値を取得しています。
See the Pen eventlistener_keydown by miyajima yuya (@pikawaka) on CodePen.
マウスオーバーした時
マウスカーソルが要素の上に置かれた時に背景色を黄色にし、離された時に白に戻る例です。
1
<div id="hoverDiv">マウスを乗せてください</div>
1
2
3
4
5
6
7
8
9
const hoverDiv = document.getElementById('hoverDiv');
hoverDiv.addEventListener('mouseover', () => {
hoverDiv.style.backgroundColor = 'yellow';
});
hoverDiv.addEventListener('mouseout', () => {
hoverDiv.style.backgroundColor = 'white';
});
要素にマウスカーソルが乗った時と外した時の処理を以下に記述します。
hoverDiv
のidを持つ要素を取得- 取得した要素に、
mouseover
とmouseout
のイベントリスナーを設定 - ユーザーが要素にマウスカーソルを乗せる
mouseover
イベントの中身の処理が実行- ユーザーが要素からマウスカーソルを外す
mouseout
イベントの中身の処理が実行
1. hoverDivのidを持つ要素を取得
1
2
3
4
5
6
7
8
9
const hoverDiv = document.getElementById('hoverDiv');
hoverDiv.addEventListener('mouseover', () => {
hoverDiv.style.backgroundColor = 'yellow';
});
hoverDiv.addEventListener('mouseout', () => {
hoverDiv.style.backgroundColor = 'white';
});
まずdocument.getElementById('hoverDiv')
でマウスカーソルを乗せる要素を取得します。
2. 取得した要素に、mouseoverとmouseoutのイベントリスナーを設定
1
2
3
4
5
6
7
8
9
const hoverDiv = document.getElementById('hoverDiv');
hoverDiv.addEventListener('mouseover', () => {
hoverDiv.style.backgroundColor = 'yellow';
});
hoverDiv.addEventListener('mouseout', () => {
hoverDiv.style.backgroundColor = 'white';
});
次に取得した要素にaddEventListener
を使用します。マウスカーソルが乗せられたときはmouseover
、外されたときはmouseout
のイベントをそれぞれ指定します。
3. ユーザーが要素にマウスカーソルを乗せる
ユーザーがブラウザに表示されている要素にマウスカーソルを乗せます。
4. mouseoverイベントの中身の処理が実行
1
2
3
4
5
6
7
8
9
const hoverDiv = document.getElementById('hoverDiv');
hoverDiv.addEventListener('mouseover', () => {
hoverDiv.style.backgroundColor = 'yellow';
});
hoverDiv.addEventListener('mouseout', () => {
hoverDiv.style.backgroundColor = 'white';
});
3でユーザーが要素にマウスカーソルを乗せたことによってmouseover
イベントの中身が実行されます。今回は要素の背景色の色を黄色に変更させています。このようにCSSを変更することでスタイルも変えることができます。
5. ユーザーが要素からマウスカーソルを外す
ユーザーが要素からマウスカーソルを外します。
6. mouseoutイベントの中身の処理が実行
1
2
3
4
5
6
7
8
9
const hoverDiv = document.getElementById('hoverDiv');
hoverDiv.addEventListener('mouseover', () => {
hoverDiv.style.backgroundColor = 'yellow';
});
hoverDiv.addEventListener('mouseout', () => {
hoverDiv.style.backgroundColor = 'white';
});
5でユーザーが要素からマウスカーソルを外したことによってmouseout
イベントの中身が実行されます。今回は要素の背景色の色を白に変更させています。
See the Pen Untitled by miyajima yuya (@pikawaka) on CodePen.
フォームが送信された時
フォームが送信された時にアラートを出す例です。
1
2
3
4
<form id="myForm">
<input type="text" name="name" required>
<button type="submit">送信</button>
</form>
1
2
3
4
5
6
const form = document.getElementById('myForm');
form.addEventListener('submit', (event) => {
event.preventDefault();
alert('フォームが送信されました!');
});
フォームが送信された場合の処理を以下に記述します。
myForm
のidを持つ要素を取得- 取得した要素にフォームが送信された場合のイベントリスナーを設定
- ユーザーがフォームを送信する
submit
イベントの中身の処理が実行
1. myFormのidを持つ要素を取得
1
2
3
4
5
6
const form = document.getElementById('myForm');
form.addEventListener('submit', (event) => {
event.preventDefault();
alert('フォームが送信されました!');
});
この例もまずdocument.getElementById('myForm')
でmyForm
というidを持つ要素を取得します。
2. 取得した要素にフォームが送信された場合のイベントリスナーを設定
1
2
3
4
5
6
const form = document.getElementById('myForm');
form.addEventListener('submit', (event) => {
event.preventDefault();
alert('フォームが送信されました!');
});
続いてフォームの送信ボタンを押した時に処理されるイベントリスナーを設定します。今回はフォームを送信した際のイベントなのでsubmit
イベントを指定します。
3. ユーザーがフォームを送信する
ユーザーがブラウザに表示されている送信ボタンを押します。
4. submitイベントの中身の処理が実行
1
2
3
4
5
6
const form = document.getElementById('myForm');
form.addEventListener('submit', (event) => {
event.preventDefault();
alert('フォームが送信されました!');
});
3でユーザーがフォームの送信ボタンを押したことによって、submit
イベントの中身のalert
が実行されます。
関数内のevent.preventDefault()
は、イベントのデフォルトの動作をキャンセルするために使用します。このコードでは、submit
イベントのデフォルトの動作であるフォーム送信とページリロードを防ぐことで、アラートを表示させています。
See the Pen eventlistener_submit by miyajima yuya (@pikawaka) on CodePen.
preventDefault()
メソッドがよくわからないです。。。
preventDefault()
メソッドはイベント発生時のデフォルト動作をキャンセルするんだ。例えばリンクを作成するaタグ
のクリックイベントでpreventDefault()
メソッドを実行すると、リンク先のページ遷移がキャンセルされるんだ。
画面がスクロールされた時
画面がスクロールされた時に右下に「トップに戻る」と表示させる例です。
1
2
<div id="content">テキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト</div>
<div id="backToTop">トップに戻る</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// ボタン要素を取得
const backToTop = document.getElementById('backToTop');
// スクロールイベントリスナーを追加
window.addEventListener('scroll', () => {
// ページが300px以上スクロールされた場合
if (window.scrollY > 300) {
backToTop.style.display = 'block'; // ボタンを表示
} else {
backToTop.style.display = 'none'; // ボタンを非表示
}
});
// ボタンクリックイベントリスナーを追加
backToTop.addEventListener('click', () => {
// ページトップへスムーズにスクロール
window.scrollTo({ top: 0, behavior: 'smooth' });
});
スクロールされた場合の処理を以下に記述します。
backToTop
のidを持つ要素を取得- 画面をスクロールした場合とボタンがクリックされた時のイベントリスナーを設定
- ユーザーが画面をスクロールする
-
scroll
イベントの中身の処理が実行 - ユーザーが「トップに戻る」ボタンをクリックする
click
イベントの中身の処理が実行
1. backToTopのidを持つ要素を取得
1
2
3
4
5
6
7
8
9
10
11
12
13
const backToTop = document.getElementById('backToTop');
window.addEventListener('scroll', () => {
if (window.scrollY > 300) {
backToTop.style.display = 'block';
} else {
backToTop.style.display = 'none';
}
});
backToTop.addEventListener('click', () => {
window.scrollTo({ top: 0, behavior: 'smooth' });
});
まずdocument.getElementById('backToTop')
でbackToTop
というidを持つ要素を取得します。
2. スクロールとクリックのイベントリスナーを設定
1
2
3
4
5
6
7
8
9
10
11
12
13
const backToTop = document.getElementById('backToTop');
window.addEventListener('scroll', () => {
if (window.scrollY > 300) {
backToTop.style.display = 'block';
} else {
backToTop.style.display = 'none';
}
});
backToTop.addEventListener('click', () => {
window.scrollTo({ top: 0, behavior: 'smooth' });
});
次に、画面がスクロールした時と、ボタンがクリックされた時に処理されるイベントリスナーを設定します。画面のスクロールイベントではwindow
オブジェクトに対してaddEventListener
を使用します。window
オブジェクトは、ブラウザの動作や情報にアクセスするために使用します。
次に、backToTop
要素に対してclick
イベントを指定します。
3. ユーザーが画面をスクロールする
ユーザーが画面をスクロールします。
4. scrollイベントの中身の処理が実行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
const backToTop = document.getElementById('backToTop');
window.addEventListener('scroll', () => {
// ページが300px以上スクロールされた場合
if (window.scrollY > 300) {
backToTop.style.display = 'block'; // ボタンが表示
} else {
backToTop.style.display = 'none'; // ボタンを非表示
}
});
backToTop.addEventListener('click', () => {
window.scrollTo({ top: 0, behavior: 'smooth' });
});
3でユーザーが画面をスクロールしたことによって、scroll
イベントの中身が実行されます。window.scrollY
で現在の垂直方向のスクロール位置をピクセル単位で取得できます。この場合、window.scrollY > 300
と指定しているので、垂直方向に300
ピクセル以上スクロールした際にbackToTop.style.display = 'block'
が実行され、「トップに戻る」ボタンが表示されます。
5. ユーザーが「トップに戻る」ボタンをクリックする
ユーザーが右下に表示された「トップに戻る」ボタンをクリックします。
6. clickイベントの中身の処理が実行
1
2
3
4
5
6
7
8
9
10
11
12
13
const backToTop = document.getElementById('backToTop');
window.addEventListener('scroll', () => {
if (window.scrollY > 300) {
backToTop.style.display = 'block';
} else {
backToTop.style.display = 'none';
}
});
backToTop.addEventListener('click', () => {
window.scrollTo({ top: 0, behavior: 'smooth' });
});
6でボタンがクリックされたことによって、click
イベントの中身のwindow.scrollTo
メソッドが実行されます。このメソッドはページを指定した位置にスクロールさせます。この場合、top: 0
としているのでページの一番上にスクロールさせます。behavior: 'smooth'
は、スクロールがスムーズに行われることを指定しています。
See the Pen eventlistener_scroll by miyajima yuya (@pikawaka) on CodePen.
使用できるオプション
addEventListener
メソッドの第三引数にはイベントリスナーのオプションを指定するためのオブジェクトを渡すことができます。このオプションオブジェクトにはいくつかのプロパティがあり、それぞれのプロパティがイベントリスナーの挙動に影響を与えます。この章ではそれぞれのプロパティとその詳細を解説します。
1
要素.addEventListener(`event`, listener, options)
capture
イベントの伝達方法を指定します。イベントはコードの記述順ではなく、特定の順序でDOMツリーを通じて伝播していきます。DOMツリーとはWebページの構造を木のように表したものです。木が根っこから枝や葉っぱに広がっていくように、DOMツリーもHTMLの要素がルートから枝分かれしています。
以下のHTMLのコードを例にします。
1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
<html>
<head>
<title>DOMツリーの例</title>
</head>
<body>
<h1>こんにちは!</h1>
<p>これはDOMツリーの簡単な例です。</p>
</body>
</html>
これがブラウザに読み込まれると、次のようなDOMツリーが作成されます。
1
2
3
4
5
6
7
8
9
html
├── head
│ └── title
│ └── "DOMツリーの例"
└── body
├── h1
│ └── "こんにちは!"
└── p
└── "これはDOMツリーの簡単な例です。"
イベントはこのDOMツリーに沿って伝わっていきます。
伝播のフェーズには、キャプチャフェーズ、ターゲットフェーズ、バブリングフェーズの3つのフェーズがあります。
- キャプチャフェーズ: イベントが一番外側の要素から内側に伝播するフェーズ
- ターゲットフェーズ: イベントが実際に起こった要素に到達するフェーズ
- バブリングフェーズ: イベントが内側の要素から外側に向かって伝播するフェーズ
capture
オプションではデフォルトはfalse
でバブリングフェーズで伝達されます。true
にするとキャプチャフェーズで伝達されます。
次のような3層構造の場合の例を見てみましょう。
1
2
3
4
5
<div id="grandparent">
<div id="parent">
<button id="child">クリック</button>
</div>
</div>
まずはデフォルトのfalse
の場合です。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const grandparent = document.getElementById('grandparent');
const parent = document.getElementById('parent');
const child = document.getElementById('child');
grandparent.addEventListener('click', () => {
alert('祖父要素がクリックされました');
});
parent.addEventListener('click', () => {
alert('親要素がクリックされました');
});
child.addEventListener('click', () => {
alert('子要素がクリックされました');
});
この場合は記述された順ではなく、バブリングフェーズ(内側から外側の要素へ)で伝わっていきます。泡が下から水面へと上がっていく様子に似ているので「バブリング」と呼ばれるようになりました。
実際にクリックして挙動を確かめてみましょう。
See the Pen Untitled by miyajima yuya (@pikawaka) on CodePen.
次はtrue
の場合です。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const grandparent = document.getElementById('grandparent');
const parent = document.getElementById('parent');
const child = document.getElementById('child');
grandparent.addEventListener('click', () => {
alert('祖父要素がクリックされました');
}, { capture: true });
parent.addEventListener('click', () => {
alert('親要素がクリックされました');
}, { capture: true });
child.addEventListener('click', () => {
alert('子要素がクリックされました');
}, { capture: true });
ture
の場合は一番外側から内側へ向かって伝わっていきます。
クリックして一番外側の要素から実行されるか確認してみましょう。
See the Pen javascript_eventlistener_true by miyajima yuya (@pikawaka) on CodePen.
once
イベントリスナーが一度だけ実行されるかどうかを指定します。デフォルトはfalse
でtrue
に設定すると、イベントリスナーはイベントが最初に発生した時だけ実行され、その後自動的に削除されます。
1
element.addEventListener('event', listener, { once: true });
例えばボタンの二度押しを防ぐ場合などに有効です。
1
2
3
4
5
const button = document.getElementById('button');
button.addEventListener('click', () => {
alert('ボタンがクリックされました');
}, { once: true });
一度クリックすると2回目は実行されないのが確認できます。
See the Pen Untitled by miyajima yuya (@pikawaka) on CodePen.
passive
このオプションをtrue
に設定すると、イベントが起こった時、そのイベントのデフォルトの動作が必ず行われます。この設定によりpreventDefault()
を呼び出しても効果がないため、ブラウザはイベントリスナーの処理を待たずにデフォルト動作を実行できるため、パフォーマンスが向上します。
以下がブラウザ処理のフローです。
- イベント発生
- イベントリスナーの呼び出し
- 処理の実行
preventDefault()
の実行有無の判定- デフォルト動作の実行 (
4
でpreventDefault()
が実行されない場合)
passive
オプションをtrue
に設定すると、ブラウザは4
の処理を省略し、常に5
のデフォルト処理を実行します。
つまり、イベントリスナーの処理が実行された後に行われる4
の処理をする必要がなくなるため、すぐにデフォルト動作が実行されパフォーマンスが向上するわけです。
これは特にスクロールイベントの際に有効です。通常、ブラウザはページがスクロールされるとき、イベントリスナーがpreventDefault()
を呼び出すかどうかを確認する必要があります。なぜならpreventDefault()
が呼び出されると、ブラウザはデフォルトのスクロール動作をキャンセルしなければならないからです。しかし、イベントリスナーのpassive
オプションをtrue
に設定すれば、ブラウザはpreventDefault()
の呼び出しを確認しないですむため、スクロール処理が即座に行われ、スクロールがよりスムーズになります。
複数のオプションを指定する場合
複数のオプションを指定するには以下のように記述します。
1
要素.addEventListener('event', listener, { capture: true , once: true, passive: true });
イベントの解除方法
removeEventListener
メソッドを使うと、登録済みのイベントリスナーを削除することができます。このメソッドを使用することで、不要なイベント処理を抑制し、パフォーマンス向上やメモリリーク防止に役立ちます。
基本的な使い方は以下の通りです。
1
要素.removeEventListener(`event`, listener, options);
各引数は以下のように指定します。
- event: イベントの種類
- listener: イベント発生時に実行される関数
- options: オプション設定(省略可能)
次の例はクリックイベントリスナーをsetTimeoutメソッドを使い、5秒後に削除しています。
1
2
3
4
5
6
7
8
9
10
11
12
13
const button = document.getElementById('button');
function handleClick(event) {
alert('ボタンがクリックされました');
}
// クリックイベントリスナーを登録
button.addEventListener('click', handleClick);
// 5秒後にクリックイベントリスナーを削除
setTimeout(() => {
button.removeEventListener('click', handleClick);
}, 5000);
5秒後にイベントリスナーが削除されているのが確認できます。
See the Pen javascript_eventlistnener_removeeventlistener by miyajima yuya (@pikawaka) on CodePen.
注意点としてイベント発生時に実行される関数は同一オブジェクトである必要があります。以下のように同じ関数を書いただけでは削除されません。
1
2
3
4
5
6
7
8
9
10
11
12
13
const button = document.getElementById('button');
// クリックイベントリスナーを登録
button.addEventListener('click', (event) => {
alert('ボタンがクリックされました');
});
// 5秒後にクリックイベントリスナーを削除
setTimeout(() => {
button.removeEventListener('click', (event) => {
alert('ボタンがクリックされました');
});
}, 5000);
以下のように5秒経ってもイベントリスナーが実行されてしまうので注意しましょう。
See the Pen javascript_eventlistnener_removeeventlistener_eroor by miyajima yuya (@pikawaka) on CodePen.
まとめ
JavaScriptのイベントリスナーは、ユーザーの操作に応じて動作するインタラクティブなWebページを作成するためのとても便利な仕組みです。イベントリスナーを駆使することで、ユーザーの操作に対して動的に反応するリッチなウェブアプリケーションを作成することができます。この記事で紹介した例を実際に試してみて、イベントリスナーの動作を確認し、理解を深めましょう!
この記事のまとめ
- イベントリスナーは、Webページ上の要素で起こるイベントを検知し、何らかの処理を実行するための仕組みです。
- イベントリスナーを使うには
addEventListener()メソッド
を使用します。 - まずは監視する要素を取得するのが重要です。