JavaScriptでボタンのクリック時の動作を処理する: addEventListenerでイベントを登録する
目次
- JavaScriptでボタンのクリックを処理する
- ボタンを取得し、リスナーを登録する
- querySelectorの使い方
- addEventListenerの使い方
- onclickによる指定
- 使用例
- 問題
JavaScriptでボタンのクリックを処理する
例えば↓のようなHTMLのボタンをクリックしたときに、アラートを表示したいとします。
<button>クリック!</button>
その場合、JavaScriptでは↓のように書くと実現できます。
const btn = document.querySelector('button') btn.addEventListener('click', () => { alert('クリックされました') })
詳しく解説していきたいと思います。
ボタンを取得し、リスナーを登録する
まず↓の部分ですが、これはdocument
のquerySelector
メソッドを使ってbutton
タグを検索し、要素を取得しています。
const btn = document.querySelector('button') console.log(btn) // <button>クリック!</button>
HTMLの要素にはリスナーを登録することが出来ます。
リスナーとは、何かイベントが発生したときに呼び出される関数のことです。
今回の場合は、ボタンがクリックされたときにアラートを表示させたいので、アラートを表示させるためのリスナー(関数)を登録します。
要素にリスナーを登録するにはaddEventListener
メソッドを使います。
addEventListener
の第1引数にはイベント名、第2引数にはリスナーを渡すことが出来ます。
よって↓のようにすることで、ボタンのクリック時のリスナーを要素に登録することが出来ます。
btn.addEventListener('click', () => { alert('クリックされました') })
↑の場合、イベント名は「click」を指定し、リスナー内ではalert
を呼び出しています。
ボタンがクリックされるとリスナーが呼ばれ、最終的にalert
が呼ばれる……という流れになります。
querySelectorの使い方
要素を検索するquerySelector
は第1引数にセレクターとなる文字列を渡します。
タグ名で取得したい場合は↓のように書き、
const btn = document.querySelector('button')
クラス名で取得したい場合は↓のよう書きます。
const btn = document.querySelector('.my-button')
ID名で取得したいなら↓のように書くことが可能です。
const btn = document.querySelector('#my-button')
HTMLのタグの親子関係などを指定することも可能です。
const btn = document.querySelector('div > button')
*正確にはDOMの親子関係ですが、ここではDOMの説明は割愛しています。
addEventListenerの使い方
addEventListener
は第1引数にイベント名、第2引数にリスナーを取ります。
第1引数のイベント名は文字列です。
第2引数は普通の関数かアロー関数を渡します。
普通の関数の場合は↓のようなコードが合法です。
function hello () { alert('hello') } const btn = document.querySelector('button') btn.addEventListener('click', hello) btn.addEventListener('click', function () { alert('bye') })
リスナーは複数登録することが可能です。
複数のリスナーを登録したい場合はaddEventListener
を複数回呼べばOKです。
アロー関数の場合は↓のようなコードが合法です。
const hello = () => { alert('hello') } const btn = document.querySelector('button') btn.addEventListener('click', hello) btn.addEventListener('click', () => { alert('bye') })
↑のJavaScriptを実行したあとにボタンをクリックすると「hello」と「bye」のアラートがそれぞれ呼ばれます。
onclickによる指定
要素にはonclick
というプロパティがあり、ここにリスナーを登録することも出来ます。
const btn = document.querySelector('button') btn.onclick = () => { alert('クリックされました') }
onclick
の場合はリスナーを複数登録することが出来ません。
拡張性などを考えるとaddEventListener
、手軽さを考えるとonclick
に軍配が上がりそうです。
使用例
ボタンのクリックをハンドリングする場合の使用例です。
クラスのメソッドをリスナーにする
クラスのメソッドをリスナーに登録したい場合は↓のようにします。
<button>クリック!</button> <script> class Clicker { constructor () { this.message = 'クリックされました' const btn = document.querySelector('button') btn.addEventListener('click', this.fire.bind(this)) } fire () { alert(this.message) } } const clicker = new Clicker() </script>
↓の行に注目してください。
btn.addEventListener('click', this.fire.bind(this))
this.fire.bind(this)
という見慣れないコードがありますが、これはfire
メソッドにbind
の引数をバインドしています。
こうしておくと、リスナーに登録したfire
メソッド内で、this
を参照することが出来るようになります。
↑のコードを実行すると「クリックされました」と表示されますが、bind
をやめて↓のようにすると
btn.addEventListener('click', this.fire)
「undefined」と表示され意図した動作をしません。
ここら辺のthis
の参照方法はJavaScriptのややこしいところなので覚えておきましょう。
リスナーにクロージャ―を登録する
複数のボタンにループ内の添え字を割り当ててalert
させたい場合を考えます。
var
を使う場合は↓のようにクロージャ―を作成すればうまくいきます。
<button>赤</button> <button>青</button> <button>黄</button> <script> const btns = document.querySelectorAll('button') for (var i = 0; i < btns.length; i++) { const closure = (function () { var number = i return function () { alert(number) } }()) const btn = btns[i] btn.addEventListener('click', closure) } </script>
これはうまくいきますが、ES6以前の古い書き方です。
現代では↓のようにカウント変数にlet
を使えばクロージャ―を使わなくても期待した動作になります。
<button>赤</button> <button>青</button> <button>黄</button> <script> const btns = document.querySelectorAll('button') for (let i = 0; i < btns.length; i++) { const btn = btns[i] const func = () => { alert(i) } btn.addEventListener('click', func) } </script>
何かの都合でvar
を使わなくてはいけない場合は、クロージャ―を使った対処方法を思い出してください。
問題
Q1: ボタンにリスナーを登録する場合、使うべきメソッドを答えよ
filter
querySelector
addEventListener
Q2: querySelector
の第1引数の型を答えよ
配列
文字列
オブジェクト
Q3: addEventListener
の第2引数にふさわしいものを答えよ
配列
関数
アロー関数
正解はこちら↓
Q1: 2, 3
Q2: 2
Q3: 2, 3