JavaScriptには、何かしらの操作のタイミングを知らせるイベントという機能があります。

例えば、キーボードを打つと音が鳴ったり、画面をスクロールするとポップアップ画像が表示されたりと、このような処理にもイベントが使われています。

このイベントに反応するために使われているのがイベントハンドラです。
今回は、イベントハンドラとは何か、その操作方法について解説します。

イベント

イベントとは、何かが起きた際に知らせる信号です。
マウスのクリックやカーソルを合わせる動き、キーボードの入力、ページの読み込みなど、ユーザーが行うさまざまなアクションを指します。

代表的なイベントには以下のようなものがあります。

  • マウスイベント
  • キーボードイベント
  • フォーム要素イベント
  • ドキュメントイベント
  • CSSイベント など

特定のイベントについては、イベントシリーズの後半の記事で解説します。

イベントハンドラ

イベントハンドラとは、イベントが発生した際に実行する関数を紐付けるための方法です。
以下のようなイベントの種類に対応したイベントハンドラを登録することができます。

  • onclick:要素がクリックされた時
  • onmouseover:要素にカーソルが置かれた時
  • onchange:要素の内容が変わった時
  • ondrag:要素がドラッグされた時
  • onsubmit:フォームが送信された時
  • onkeypress:キーが押された時
  • onload:ページが読み込まれた時 など

on + イベント名のように記述します。

イベントハンドラの登録方法

イベントハンドラを登録する方法はいくつかありますが、ここでは以下の2つの方法を見ていきましょう。

HTML属性

はじめは、HTML要素の属性にイベントハンドラを登録する方法です。
イベントハンドラをHTML要素の属性に割り当てるため、HTML上で設定を行います。

例えば、input要素に対してonclickを使用すると、このように記述することができます。

<p>Click this button.</p>
<input type="button" value="button" onclick="console.log('Clicked')">

onclick属性に対する値として、実行したい関数を記述します。
ここでは、console.log('Clicked')を属性値として割り当てることで、要素がクリックされた時に”Clicked”と出力されるようになります。

eventhandler_1

HTML属性に直接コードを書くだけでなく、JavaScriptで関数を作成し、イベントハンドラとしてその関数を呼び出すこともできます。その場合、onイベント名="関数()"のように記述します。

以下のコードは、別途定義したchangeText関数をイベントハンドラに割り当てています。

<p id="text">Click this button.</p>
<input type="button" value="button" onclick="changeText()">

<script>
  function changeText() {
    let getText = document.getElementById('text');
    getText.textContent = 'You clicked!';
  }
</script>

クリック前:
eventhandler_2

クリック後:
eventhandler_3

ボタンをクリックすると”Click this button”から”You clicked”というテキストに変わりました。

DOMプロパティ

もう一つは、DOMプロパティを使ってイベントハンドラを登録する方法です。
要素のプロパティに対してイベントハンドラを割り当てるため、JavaScript上で設定を行います。

では、input要素に対してonclickを使用し、イベントハンドラを登録してみましょう。

<p>Click this button.</p>
<input id="elem" type="button" value="button">

<script>
  let elem = document.getElementById('elem');
  elem.onclick = function() {
    console.log('Clicked'); 
  };
</script>

elem.プロパティ = イベントハンドラのように、要素のプロパティに対して実行したい関数を紐付けます。
ボタンをクリックすると”Clicked”とコンソール出力されます。

eventhandler_4

別途用意した関数をイベントハンドラに割り当てることもできます。

function sayClicked() {
  console.log('Clicked'); 
}

elem.onclick = sayClicked;

また、イベントハンドラが登録されているプロパティに対してnullを代入すると、イベントハンドラを解除することができます。

elem.onclick = null;

イベントハンドラの記述の違い

以下の2つは同じように動作します。

HTML属性に割り当て:

<input type="button" value="button" onclick="sayClicked()">
<script>
  function sayClicked() {
    console.log('Clicked'); 
  }
</script>

DOMプロパティに割り当て:

<input id="elem" type="button" value="button">
<script>
  function sayClicked() {
    console.log('Clicked');
  }

  let elem = document.getElementById('elem');
  elem.onclick = sayClicked; 
</script>

onclickは、どちらもすべて小文字で記述していますが、2つの方法には違いがあります。

まず、HTML属性は大文字と小文字を区別しません。そのため、onclick以外にもONCLICKonCLlickなどでも同じ動作をします。通常はonclickようにすべて小文字表記にします。

 <!-- すべてOKだが、通常はすべて小文字 -->
<input onclick="">
<input ONCLICK="">
<input onClick="">

一方、DOMプロパティでは大文字と小文字を区別します。そのため、onclickのようにすべて小文字表記にします。

// すべて小文字
elem.onclick = function() {};

また、関数の記述方法にも違いがあります。
HTML属性へ関数を割り当てる際には、関数()のように関数の後ろに括弧を付けるのに対して、DOMプロパティでは括弧を付けません。

HTML属性に割り当て:

<!-- 正しい -->
<input type="button" value="button" onclick="sayClicked()">
<!-- 誤り -->
<input type="button" value="button" onclick="sayClicked">

DOMプロパティに割り当て:

// 正しい
elem.onclick = sayClicked;
// 誤り
elem.onclick = sayClicked();

イベントハンドラは一つのみ割り当て可

HTML属性やDOMプロパティにイベントハンドラを登録した際、同じイベントに対して登録できるイベントハンドラは一つのみです。

以下のように、一つ以上のイベントハンドラを割り当てようとすると、既存のイベントハンドラが新しいものに上書きされます。

<p>Click this button.</p>
<input id="elem" type="button" value="button" onclick="console.log('Hello!')">

<script>
  // 新しいイベントハンドラ
  let elem = document.getElementById('elem');
  elem.onclick = function() {
    console.log('Thank you!'); // "Thank you!"
  };
</script>

eventhandler_5

まとめ

今回は、イベントハンドラの登録方法について解説しました。

// ポイント
* イベントは、ユーザーが行うさまざまなアクション
* イベントハンドラは、イベントが発生した際に実行する関数を紐付けるための方法
* HTML属性に割り当て:onclick="..."
* DOMプロパティに割り当て:elem.onclick = function() {}
* 同じイベントに対して登録できるイベントハンドラは一つのみ

イベントハンドラは、イベント操作でもっとも基礎的で重要な機能です。ポイントをおさえて理解に繋げていきましょう。

合わせて読みたいイベント概要シリーズ

第1回:イベントハンドラ(当記事)
第2回:イベントリスナー
第3回:イベントオブジェクト
第4回:バブリングとキャプチャリング
第5回:Event.targetとEvent.currentTarget
第6回:イベント移譲
第7回:デフォルト動作のキャンセル
第8回:新しいイベントの発生