ユーニックス総合研究所

  • home
  • archives
  • js-button-click-event

JavaScriptでボタンのクリック時の動作を処理する: addEventListenerでイベントを登録する

  • 作成日: 2020-08-18
  • 更新日: 2023-12-28
  • カテゴリ: JavaScript

JavaScriptでボタンのクリックを処理する

例えば↓のようなHTMLのボタンをクリックしたときに、アラートを表示したいとします。

<button>クリック!</button>  

その場合、JavaScriptでは↓のように書くと実現できます。

const btn = document.querySelector('button')  
btn.addEventListener('click', () => {  
    alert('クリックされました')  
})  

詳しく解説していきたいと思います。

ボタンを取得し、リスナーを登録する

まず↓の部分ですが、これはdocumentquerySelectorメソッドを使って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: ボタンにリスナーを登録する場合、使うべきメソッドを答えよ

  1. filter
  2. querySelector
  3. addEventListener

Q2: querySelectorの第1引数の型を答えよ

  1. 配列
  2. 文字列
  3. オブジェクト

Q3: addEventListenerの第2引数にふさわしいものを答えよ

  1. 配列
  2. 関数
  3. アロー関数

正解はこちら↓

Q1: 2, 3
Q2: 2
Q3: 2, 3