jQueryでイベントハンドラを使おう!

jQueryでイベントハンドラを使おう!

イベントハンドラとは、ある一定の出来事が発生したときに行われる処理のことです。

.on()でイベントハンドラを追加、登録しよう!

  • .on(), .one()によるイベントハンドラの追加、登録
  • 複数イベントへのイベントハンドラの追加
  • .off()によるイベントハンドラの削除
  • changeイベントへのイベントハンドラの追加

これらの項目については、以下の記事を参照してください。

イベントハンドラを取得するには?

以下の記事の「イベントを取得するには?」を参照してください。

イベントハンドラの引数は?

$('input').on('change', function(event) {
    ...
});

イベントハンドラには、引数としてイベントオブジェクトが渡されます。

オブジェクトなので、例えば、event.currentTargetのような記述で各プロパティにアクセスできます。

イベントオブジェクトのプロパティ一覧

イベントオブジェクトに格納されているプロパティを一覧にしました。

event.currentTargetイベントが発生している現在のDOM要素
event.data実行中のイベントハンドラがバインドされたとき、イベントメソッドに渡されたオプションのデータオブジェクト
event.delegateTarget現在呼び出されているイベントハンドラが帰属する要素
event.isDefaultPrevented()イベントオブジェクト上でevent.preventDefault()が呼び出されたか否かを返します
event.isImmediatePropagationStopped()イベントオブジェクト上でevent.stopImmediatePropagation()が呼び出されたか否かを返します
event.isPropagationStopped()イベントオブジェクト上でevent.stopPropagation()が呼び出されたか否かを返します
event.metaKeyイベントが発生したとき、メタキーが押されていたか否かを表します。メタキーとは、Macのコマンドキー、WindowsのWindowsキーです。
event.namespaceイベントが実行された名前空間
event.pageXドキュメントの左端から計算したマウスの相対位置
event.pageYドキュメントの上端から計算したマウスの相対位置
event.preventDefault()このメソッドが呼び出されると、イベントのデフォルト動作が実行されません。
event.relatedTargetイベントに関連する他のDOM要素。mouseoutの場合、マウスが侵入した要素を表し、mouseoverの場合、マウスが離れた要素を表します。
event.resultイベントハンドラが返した最後の値
event.stopImmediatePropagation()残りのイベントハンドラの実行、イベントのDOMツリーへのバブリングを停止します。
event.stopPropagation()イベントのDOMツリーへのバブリング、親要素のイベントハンドラへのイベントの通知を停止します。
event.targetイベントが開始されたDOM要素
event.timeStamp1970年1月1日からブラウザでイベントが発生した時間までのミリ秒単位の時間
event.typeイベントの性質
event.whichキーイベント、マウスイベントで押された特定のキー、ボタン

その他のプロパティは、event.originalEventに格納されています。

event.dataとは?

$('input').on('change', {value: 1}, function(event) {
    console.log(event.data.value);
});

.on()の第2引数にオブジェクトを渡すことで、イベントオブジェクトのevent.dataから参照できます。

イベントハンドラをバインドした時点での値を使用したい場合に便利です。

サンプルでは、event.data.valueで渡されたプロパティがvalueの値を取得し、console.log()でコンソール出力しています。

$(document).on('change', 'input', {value: 1}, function(event) {
    console.log(event.data.value);
});

第2引数にセレクタを指定した場合、event.dataは第3引数で渡します。

event.delegateTargetとは?

$('#wrapper').on('change', 'input', function(event) {
    ...
});

event.delegateTargetは、.on()を実行した要素を表します。

サンプルのevent.delegateTargetは、idがwrapperのDOM要素になります。

セレクタで指定されたinput要素は、event.currentTargetに格納されます。

$('input').on('change', function(event) {
    ...
});

セレクタを指定しない場合、event.currentTargetとevent.delegateTargetは同じ要素を表します。

バブリングとは?

<div> 
    <button>ボタン</button>
</div>
$('button').on('click', function(event) {
    console.log('button');
});

$('div').on('click', function(event) {
    console.log('div');
});
button
div

div要素の子要素としてボタンを設置し、各々クリックされたときにコンソール出力するイベントを追加しています。

サンプルでは、ボタンをクリックすると、ボタンのクリックイベントが発生し、buttonがコンソール出力されます。

ボタンはdiv要素上に存在しているため、このクリックイベントは、div要素にも伝播します。

この子要素から親要素にイベントが伝わる動きをバブリングと呼びます。

$(document).on('click', function(event) {
    console.log('document');
});

直近の親要素だけではなく、body, htmlを経てdocumentまで伝播します。

ボタンをクリックしたとき、documentにクリックイベントを指定していれば、バブリングにより、documentのイベントハンドラも実行されることになります。

event.stopPropagation()とは?
$('button').on('click', function(event) {
    console.log('button');
    
    event.stopPropagation();
});

$('div').on('click', function(event) {
    console.log('div');
});
button

ボタンのクリックイベントに、event.stopPropagation()を追加しています。

event.stopPropagation()は、親要素へのバブリングを停止するメソッドです。

サンプルでは、ボタンのイベントは親要素のdiv要素に伝播せず、div要素のイベントハンドラは実行されません。

event.stopImmediatePropagation()とは?
$('button').on('click', function(event) {
    console.log('button1');
});

$('button').on('click', function(event) {
    console.log('button2');
});
button1
button2

ボタンのクリックイベントを2つ追加しています。

イベントハンドラは、追加された順番で実行されので、サンプルでは、button1, button2の順にコンソール出力されます。

$('button').on('click', function(event) {
    console.log('button1');

    event.stopImmediatePropagation();
});

$('button').on('click', function(event) {
    console.log('button2');
});
button1

1つ目のボタンのクリックイベントにevent.stopImmediatePropagation()を追加しています。

event.stopImmediatePropagation()は、event.stopPropagation()と同様、親要素へのバブリングを停止するのに加え、それ以降のイベントハンドラの実行を中止するメソッドです。

サンプルでは、button1のみがコンソール出力され、button2は出力されません。

event.whichとは?

マウスイベント

mousedown, mouseupイベントでは、event.whichは、マウスのボタンを表します。

1が左クリック、2がミドルクリック、3が右クリックです。

キーボードイベント
<input type="text" />
<div></div>
$('input').on('keydown', function(event) {
    $(this).next().html(event.which);
    
    $(this).val('');
});

keydown, keypress, keyupイベントでは、event.whichは、キーボードのキーコードを表します。

キーコードとは、例えば a なら 65 のように、入力したキーに対応する数字のことです。

サンプルでは、input要素に文字を入力すると、.html()で直後の要素のHTMLコンテンツをevent.which、つまりキーコードに変更しています。

入力後、.val()に空文字を渡し、input要素の値を初期化しています。

イベントハンドラの順番を変更するには?

$('button').on('click', function(event) {
    console.log('button1');
});

$('button').on('click', function(event) {
    console.log('button2');
});

let events = $._data($('button')[0], 'events');

let click_events = [events.click[1], events.click[0]];

events.click = Object.assign(events.click, click_events);
button2
button1

ボタンのクリックイベントにつき、イベントハンドラ実行の順番を変更しています。

let events = $._data($('button')[0], 'events');

$._data()の第1引数にイベントをバインドしているDOM要素、第2引数に’events’を渡し、イベントのデータを取得しています。

第1引数には、jQueryオブジェクトではなく、DOM要素を渡すことに注意しましょう。

1番目の要素であれば、jQueryオブジェクトの後方に [0] を追加すれば、DOM要素を取得できます。

let click_events = [events.click[1], events.click[0]];

イベントのデータは、イベント名をプロパティ、イベントハンドラの配列を値とするオブジェクトです。

サンプルでは、クリックイベントなので、events.clickに格納されています。

1番目のボタンのクリックイベントがevents.click[0], 2番目がevents.click[1]です。

順番を入れ替えるため、2番目のイベントを1番目、1番目のイベントを2番目に格納した配列click_eventsを宣言します。

events.click = Object.assign(events.click, click_events);

Object.assign()の第1引数に元のイベントオブジェクト、第2引数に順番を入れ替えた配列を渡し、events.clickをclick_eventsで上書きします。

Object.assign()により、events.clickに含まれているイベントハンドラ以外の情報を保持した上で、イベントハンドラの順番のみを入れ替えた新しいオブジェクトを生成できます。

このオブジェクトをevents.clickに代入すれば、イベントハンドラの入れ替えは完了です。

events.clickにclick_eventsをそのまま代入すると、クリックイベント自体が発生しなくなるので、注意しましょう。

まとめ

  • イベントハンドラの引数は、イベントオブジェクトです。
  • イベントハンドラの順番を変更するには、$._data()を使用します。

実践カテゴリの最新記事