【jQuery】trigger()メソッド完全ガイド|カスタムイベント・triggerHandler()との違い・実用パターンまで

trigger() はjQueryの要素に紐付いたイベントハンドラーをプログラムから強制的に呼び出すメソッドです。「ページ読み込み時にchangeイベントを1回走らせて初期状態を同期する」「テスト中にクリックイベントを自動発火させる」など、実務でよく使われます。

この記事でわかること

  • trigger()の基本構文とよく使うイベントのトリガー方法
  • trigger()とtriggerHandler()の違いと使い分け
  • on()で定義したカスタムイベントをtriggerで発火させる方法
  • イベントハンドラーにパラメーターを渡す方法
  • イベントバブリングの制御(stopPropagation連携)
  • 読み込み時初期化・フォーム連動・タブUI連動の実用パターン
スポンサーリンク

基本構文とよく使うイベントのトリガー

$("セレクター").trigger("イベント名") で対象要素のイベントを発火させます。クリック・フォーカス・changeなど、標準イベントはすべて発火できます。

// クリックイベントを強制発火
$('#submit-btn').trigger('click');

// 省略形(.click()/.change() もtrigger()と同義)
$('#submit-btn').click();   // trigger('click') と同じ

// changeイベントを発火(セレクトボックスの選択変更処理を再実行)
$('#category').trigger('change');

// フォーカスを当てる
$('#search-input').trigger('focus');

// keyupイベントを発火
$('#filter-input').trigger('keyup');
trigger()はイベントハンドラーを呼ぶ。ブラウザ動作とは別
$('#submit-btn').trigger('click') はボタンに登録されたjQueryのclickハンドラーを実行しますが、ブラウザネイティブのクリック(フォーム送信・アンカー遷移など)は発生しない場合があります。ネイティブ動作も含めて発火させたい場合は $('#submit-btn')[0].click()(DOMネイティブ)を使ってください。

trigger()とtriggerHandler()の違い

triggerHandler()trigger() と似ていますが、バブリングしない・ブラウザのデフォルト動作を発生させない・最初の要素のみ対象という3つの違いがあります。

違い trigger() triggerHandler()
イベントバブリング 発生する 発生しない
ブラウザのデフォルト動作 発生する場合がある 発生しない
対象要素数 マッチした全要素 最初の1要素のみ
戻り値 jQueryオブジェクト(チェーン可) 最後のハンドラーの戻り値
// trigger() の例: バブリングあり・全要素対象
$('input[type="text"]').trigger('focus');
// → 全てのテキスト入力にfocusイベントが発火し、
//   ブラウザのフォーカス枠も表示される

// triggerHandler() の例: バブリングなし・最初の要素のみ
$('input[type="text"]').triggerHandler('focus');
// → 最初のinputのfocusハンドラーだけ実行
//   ブラウザのフォーカス枠は表示されない

// 典型的な使い分け
// trigger('change')  → changeハンドラー + ブラウザ動作を両方発火させたい場合
// triggerHandler('change') → ハンドラーだけ呼びたい(フォーム送信などを避けたい)場合
フォームのsubmitにtrigger()を使うと送信が発生する
$('form').trigger('submit') はsubmitハンドラーを実行した後、ブラウザのフォーム送信も発生します。バリデーションハンドラーだけを再実行したい場合は $('form').triggerHandler('submit') を使うか、ハンドラー内で e.preventDefault() を呼んでください。

カスタムイベントの定義とtrigger()で発火させる

独自のイベント名を on() で定義し、trigger() で呼び出すことでコンポーネント間の疎結合な通信が実現できます。

// カスタムイベントを定義
$(document).on('cart:updated', function (e, itemCount) {
  // カートが更新されたときの処理
  $('#cart-count').text(itemCount);
  $('#cart-icon').addClass('is-updated');
});

// 商品追加処理(どこからでも発火できる)
$('#add-to-cart').on('click', function () {
  var newCount = 5;  // 実際はDBやAPIから取得
  $(document).trigger('cart:updated', [newCount]);
});

// 名前空間付きカスタムイベント(推奨)
// 'cart:updated' のようにコロンで名前空間を区切ると
// イベント名の衝突を防げる
カスタムイベントでコンポーネントを疎結合にする
カートの更新処理と表示更新処理を直接呼び合うのではなく、cart:updated イベントを仲介することで、どちらかの実装が変わってももう一方を修正する必要がありません。カスタムイベントはjQuery独自の仕組みで、DOMのネイティブイベントとは独立しています。

イベントハンドラーにパラメーターを渡す

trigger("イベント名", [値1, 値2, ...]) の第2引数に配列を渡すと、イベントハンドラーの第2引数以降に値が渡されます。

// パラメーターを受け取るハンドラー
$('#my-elem').on('dataLoaded', function (e, data, source) {
  console.log('data:', data);     // { id: 1, name: 'foo' }
  console.log('source:', source); // 'api'
});

// パラメーターを渡してtrigger
$('#my-elem').trigger('dataLoaded', [{ id: 1, name: 'foo' }, 'api']);

// Eventオブジェクトを経由してデータを渡す方法
var ev = $.Event('dataLoaded');
ev.detail = { id: 1, name: 'foo' };
$('#my-elem').trigger(ev);
// ハンドラー内: e.detail.id でアクセス
$.Event()でイベントオブジェクトを事前に作成できる
$.Event("イベント名") でEventオブジェクトを事前に生成し、プロパティを自由に追加してからtriggerに渡せます。カスタムデータをイベントに紐付けたい場合に便利です。

バブリング制御との組み合わせ

trigger()で発火したイベントも通常のイベントと同様に親要素へバブリングします。意図しない親要素のハンドラーが呼ばれる場合は stopPropagation() と組み合わせます。

// バブリングを確認する例
$(document).on('click', function () {
  console.log('document clickハンドラーが呼ばれた');
});

$('#btn').on('click', function () {
  console.log('#btn clickハンドラーが呼ばれた');
});

// trigger('click') はバブリングするため両方が呼ばれる
$('#btn').trigger('click');
// ログ: '#btn clickハンドラーが呼ばれた'
// ログ: 'document clickハンドラーが呼ばれた'

// triggerHandler('click') はバブリングしないため#btnのみ
$('#btn').triggerHandler('click');
// ログ: '#btn clickハンドラーが呼ばれた'(のみ)

実用パターン集

読み込み時に初期状態を同期する

changeイベントに状態同期のロジックを書いておき、ページ読み込み時に trigger("change") を呼ぶだけで初期化できます。

$(function () {
  // カテゴリ変更時の処理(フォーム操作時と読み込み時の両方で使う)
  $('#category').on('change', function () {
    var selected = $(this).val();
    if (selected === 'other') {
      $('#other-field').show();
    } else {
      $('#other-field').hide();
    }
  });

  // 読み込み時にtriggerで初期化(コードの重複なし)
  $('#category').trigger('change');
});
初期化コードの重複を避けるパターン
changeイベントハンドラーに処理を書いておき、読み込み時に trigger("change") を呼ぶことで、同じ処理を2箇所に書く必要がなくなります。ページ読み込み時のチェックボックス初期化完全ガイドでも同様のパターンを解説しています。

タブUIで他のタブ切り替えに連動する

$(function () {
  // タブ切り替えカスタムイベント
  $(document).on('tab:changed', function (e, tabId) {
    // グラフやデータの更新など複数コンポーネントが反応
    console.log('タブが切り替わりました:', tabId);
    updateChart(tabId);
    loadTabData(tabId);
  });

  $('.tab-btn').on('click', function () {
    var tabId = $(this).data('tab');
    $('.tab-btn').removeClass('is-active');
    $(this).addClass('is-active');
    $(document).trigger('tab:changed', [tabId]);
  });
});

フォーム送信前のバリデーション再実行

$(function () {
  // 各フィールドにblurバリデーションを設定
  $('input[required]').on('blur', function () {
    if (!$(this).val()) {
      $(this).addClass('is-error');
    } else {
      $(this).removeClass('is-error');
    }
  });

  // 送信時に全フィールドのblurを強制発火してバリデーション
  $('form').on('submit', function (e) {
    $('input[required]').trigger('blur');  // 全フィールドをまとめてバリデーション

    if ($('.is-error').length > 0) {
      e.preventDefault();  // エラーがあれば送信阻止
    }
  });
});
submit時にblur triggerでバリデーションを統一する
blurイベントにバリデーションロジックを書いておき、フォーム送信時に全フィールドで trigger("blur") を呼ぶことで、送信前に全フィールドを一括チェックできます。フォームバリデーション完全ガイドも参照してください。

テスト・デバッグでの活用

ブラウザコンソールや自動テストから trigger() を使ってUIの動作確認やデバッグができます。

// ブラウザコンソールから実行する例
$('#upload-input').trigger('change');   // ファイル選択後の処理を再実行
$(window).trigger('resize');           // リサイズイベントを手動発火
$(window).trigger('scroll');           // スクロールイベントを手動発火

// jQuery QUnit / Jasmine などのテストでの使用例
// QUnit
QUnit.test('submitボタンクリックでフォームが送信される', function (assert) {
  var submitted = false;
  $('#my-form').on('submit', function (e) {
    e.preventDefault();
    submitted = true;
  });
  $('#submit-btn').trigger('click');
  assert.ok(submitted, 'フォームが送信された');
});
trigger()はjQueryハンドラーのみを呼ぶ
Vanilla JS(addEventListener)で登録されたイベントリスナーはtrigger() では呼ばれません。Vanilla JSのリスナーも含めて発火させたい場合はelement.dispatchEvent(new Event("click")) を使ってください。

trigger()・triggerHandler()・dispatchEvent()の比較

メソッド バブリング Vanilla JSリスナーも呼ぶ 全要素対象 向いている用途
trigger() jQueryハンドラーの一括発火・UI連動
triggerHandler() ✗(最初の1つ) 副作用なしの安全なハンドラー実行
dispatchEvent() —(1要素ずつ) Vanilla JS混在・テスト

まとめ

trigger() は「ハンドラーを再利用して重複コードを避ける」「カスタムイベントでコンポーネントを疎結合にする」「テスト・デバッグでUIの動作を確認する」など、実務で幅広く活用できます。triggerHandler() との違いを押さえることが、バグのない実装への近道です。

関連記事: ページ読み込み時のチェックボックス初期化完全ガイド / フォームバリデーション完全ガイド / each()でループする完全ガイド

よくある質問(FAQ)

Qtrigger(“click”)とDOM要素の.click()の違いは?
A$("selector").trigger("click")$("selector").click() は全く同じ動作です。.click()trigger("click") の省略形です。なお $(element)[0].click()(ネイティブDOM)はブラウザのクリックイベントを発生させるため、リンクの遷移・フォームのsubmitなどネイティブ動作も含めて実行されます。
Qtrigger()してもハンドラーが呼ばれません。
A主な原因は (1) セレクターが要素に一致していない、(2) on() でイベントが登録される前に trigger() を呼んでいる、(3) Vanilla JS(addEventListener)で登録されたハンドラーはtrigger()では呼ばれない、の3つです。コンソールで $("selector").length を確認してセレクターが一致しているか確認してください。
Qカスタムイベント名に使える文字に制限はありますか?
AjQueryのカスタムイベント名には英数字・コロン(:)・ハイフン(-)・ドット(.)が使えます。ドットは名前空間として扱われます(例: click.myModulemyModule 名前空間のclickイベント)。コロンは名前空間の区切りとして慣習的に使われます(例: cart:updated)。
Q$(window).trigger(“resize”)が動作しません。
Aresizeハンドラーを $(window).on("resize", fn) で登録していれば動作します。ただしブラウザウィンドウのサイズ変更は実際には発生しないため、サイズ依存の計算($(window).width() など)は実際のサイズを返します。グラフやスライダーの再描画など「resizeに反応する処理を手動で実行したい」場合に有効です。
Qon()で登録したカスタムイベントはoff()で解除できますか?
Aはい。$(el).off("cart:updated") でカスタムイベントのハンドラーを解除できます。名前空間を使っている場合は $(el).off("cart:updated.myModule") のように名前空間込みで指定することで、他のモジュールのハンドラーに影響を与えずに解除できます。