jQuery on()の使い方|イベント登録・off()・名前空間・one()

jQuery onの使い方とは

.on() は、jQuery 1.7 以降でイベントを登録する基本のメソッドです(公式ドキュメントは、イベント登録に必要な機能をすべて備えると説明しています)。クリックなどのイベントを登録する基本から、複数イベント・名前空間・データ渡し・一度だけの実行まで、これ1つで書けます。古い .bind() .live() .delegate() の代わりでもあり、.bind() と .delegate() は 3.0 で非推奨になりました。

基本(構文)

$(selector).on(events [, selector] [, data], handler);
使い方 例
基本 $('.btn').on('click', fn)
複数イベント $('.btn').on('mouseenter mouseleave', fn)
連想配列 $('.btn').on({ mouseenter: fn1, mouseleave: fn2 })
名前空間 $('.btn').on('click.myNs', fn)
データ渡し $('.btn').on('click', { who: 'bob' }, fn)
一度だけ $('.btn').one('click', fn)
解除 $('.btn').off('click')
委譲 $('#list').on('click', '.del', fn)(jQuery イベント委譲 で解説)

ハンドラの中では this がイベントが付いた要素(素のDOM要素)、event.currentTarget も同じ要素を指します。jQueryオブジェクトとして使うときは $(this) と書きます($(this) と each())。

サンプルコード(実行結果つき)

$('.btn').on('click', function (e) {
  console.log(e.type, this.tagName, this === e.currentTarget);
});
$('.btn').on('click.myNs', function () { console.log('ns'); });
$('.btn').on('click', { who: 'bob' }, function (e) { console.log('data=' + e.data.who); });
$('.btn').trigger('click');

実行結果:

click BUTTON true
ns
data=bob

登録した順に、3つのハンドラが呼ばれました。名前空間だけを外すには次のように書きます。

$('.btn').off('click.myNs');
$('.btn').trigger('click');   // click BUTTON true / data=bob(nsは出ない)
$('.btn').off('click');       // 残りをすべて解除

カスタムイベントと引数も渡せます。

$(document).on('app:save', function (e, a, b) { console.log('save', a, b); });
$(document).trigger('app:save', ['x', 2]);   // save x 2

リンクの既定動作を止める preventDefault() は、呼ぶ前後で e.isDefaultPrevented() が false から true に変わりました。

動作確認(検証環境と結果)

  • 環境: Node.js v24.19.0 / jsdom 30.1.2 / jQuery 3.7.1
  • 実行: node t3.js(検証ログは testsjquery-on-event.md)
  • 結果: 上の出力のとおり。return false を返すハンドラを付けると、親要素(#wrap)に付けたクリックのハンドラは呼ばれませんでした(return false は preventDefault() と stopPropagation() の両方を行います)。
  • 型の確認: $.fn.bind $.fn.delegate は 3.7.1 でも関数として存在しますが、3.0 から非推奨です。$.fn.live は存在しません。
  • 実ブラウザでの実クリック(マウス操作)は未検証です。上記は .trigger('click') による検証です。

jQuery onの使い方の注意点

  • return false は2つの動作をまとめて行うため、親へのイベント伝播まで止まります。意図が preventDefault() だけなら、そちらを明示します。
  • .trigger('click') は jQuery で登録したハンドラのほか、素の addEventListener で登録したハンドラも呼びました。ただし呼ばれる順序は異なる場合があるため、混在させないほうが安全です。
  • ハンドラを .off() するには、同じ関数への参照が必要です。無名関数で登録したときは、名前空間(click.myNs)で外すと楽です。
  • 同じ要素に同じ処理を二重に登録しやすいので、.off('click.myNs').on('click.myNs', fn) の形で重複を避ける方法もあります。
  • アロー関数をハンドラにすると this が要素を指しません。要素が必要なら e.currentTarget を使います。

jQuery onの使い方でよくあるミス

  • 動的に追加した要素にクリックが効かない。直接登録では後から増えた要素に付かないため、委譲を使います。
  • .click(fn) などの省略形と .on('click', fn) を混在させる。省略形も使えますが、.on() に統一するほうが読みやすいです。
  • .hover(fn1, fn2) を使い続ける。3.3 から非推奨です。mouseenter / mouseleave を .on() で登録します。
  • .off() を引数なしで呼び、他のスクリプトが登録したハンドラまで消す。

ブラウザ対応・バージョン

.on() は 1.7 で追加され、3.7.1 でも使えます。.bind() と .delegate() は 3.0 で非推奨、.live() は 3.7.1 には存在しません。素のJavaScriptでは addEventListener が同じ役割で、{ once: true } オプションが .one() に相当します(jQueryから素のJSへの移行)。

jQuery onの使い方のチェックリスト

  • .bind() .delegate() ではなく .on() を使っている。
  • 解除する可能性があるハンドラに名前空間を付けた。
  • return false の意図(既定動作の停止+伝播の停止)を理解している。
  • 動的に増える要素には委譲を使っている。
  • アロー関数でなく function のハンドラで this を使っている(または e.currentTarget を使っている)。

jQuery onの使い方のFAQ(よくある質問)

.on(‘click’) と .click() はどちらがよいですか。

動作は同じです。名前空間・委譲・データ渡しなどが必要になるため、.on() に揃えるのが無難です。

一度だけ実行したいときは。

.one('click', fn) を使います。

登録済みのハンドラを確認できますか。

内部API $._data(el, 'events') で見られますが、非公開の仕様なので、デバッグ以外では使わない前提です。

筆者の見解(jQuery onの使い方)

イベントの登録は .on() と .off() の2つだけ覚えれば足ります。名前空間は地味ですが、後からプラグインや別機能が同じ要素にイベントを足したときに、自分の分だけを安全に外せるため、実務ではかなり効くと考えます。

jQuery onの使い方の関連項目

出典(一次情報)

タイトルとURLをコピーしました