jQuery / Method / .click() - クリック時の処理を登録するメソッド

jQueryの .click(handler) はクリック時に動く関数を登録し、引数なしの .click() はイベントを実行する短縮メソッドです。新しいコードでは登録に .on("click", handler)、実行に .trigger("click") を使います。後で追加するボタンも扱うなら、残り続ける親へイベントを委譲します。

登録と実行を分けて移行する

.click() の公式文書はjQuery 3.3から非推奨としています。非推奨と削除は異なり、この短縮形と代替形は3.7.1と4.0.0の両方で実行できました。ただし新しいコードは案内されている.on()と.trigger()で書きます。

目的 以前の短縮形 推奨形
現在の要素へ関数を登録 .click(handler) .on("click", handler)
コードからイベント実行 .click() .trigger("click")
将来の子孫にも適用 既存要素への直接登録だけでは不足 親の.on("click", 子孫セレクター, handler)

handlerはイベント時に動かす関数です。handler()と即時実行せず関数を渡します。直接登録は.on()時点で要素が必要なので、例では文書準備後に維持される親を選びます。

クリック・実行・解除を比べる完全な例

全コードをUTF-8の click-demo.html に保存し、ブラウザーで開きます。インストールは不要ですが、CDN(Content Delivery Network、コンテンツ配信ネットワーク)から公式jQueryファイルを読む接続が必要です。コードは4.0.0を使い、クリック・追加・再登録・解除・リセットは3.7.1と4.0.0で実行確認しました。

Alphaと追加するBetaが処理対象で、他の実習操作ボタンは回数に含めません。対象の名前と累積回数を表示し、強調を切り替えます。すべてtype="button"なので、フォームに置いても意図せず送信しません。

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Click handlers and delegated events</title>
  <style>
    body { font: 16px/1.6 sans-serif; margin: 24px; }
    button { padding: 10px; margin: 4px; }
    .item.selected { outline: 3px solid #b66b00; background: #fff3cf; }
    #items { border: 1px solid #ccc; padding: 12px; }
  </style>
  <script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
</head>
<body>
  <h1>Click handlers and delegated events</h1>
  <div id="items">
    <button type="button" class="item" id="first"><span>Alpha</span></button>
  </div>
  <button type="button" id="add">Add Beta</button>
  <button type="button" id="trigger">Trigger Alpha</button>
  <button type="button" id="bind">Enable or rebind</button>
  <button type="button" id="stop">Stop demo handler</button>
  <button type="button" id="reset">Reset</button>
  <p>Handler: <span id="status"></span></p>
  <p id="result" aria-live="polite"></p>
  <script>
    $(function () {
      let clicks = 0;
      let last = "none";
      function render() {
        $("#result").text(`last=${last} | clicks=${clicks}`);
      }
      function handleClick(event) {
        clicks++;
        last = $(this).text();
        $(this).toggleClass("selected");
        render();
      }
      function bind() {
        $("#items").off("click.demo", ".item")
          .on("click.demo", ".item", handleClick);
        $("#status").text("enabled");
      }
      $("#add").on("click", function () {
        if (!$("#second").length) {
          $("<button>").attr({ type: "button", id: "second" })
            .addClass("item").text("Beta").appendTo("#items");
        }
      });
      $("#trigger").on("click", () => $("#first").trigger("click"));
      $("#bind").on("click", bind);
      $("#stop").on("click", function () {
        $("#items").off("click.demo", ".item");
        $("#status").text("stopped");
      });
      $("#reset").on("click", function () {
        $("#second").remove();
        $("#first").removeClass("selected");
        clicks = 0;
        last = "none";
        bind();
        render();
      });
      bind();
      render();
    });
  </script>
</body>
</html>

初期のHandlerはenabledで、結果は次のとおりです。

last=none | clicks=0
  1. Alpha で last=Alpha | clicks=1 と強調が生じます。Trigger Alpha は同じボタンをコードで実行し、回数2と強調なしになります。
  2. Add Beta 後に Beta を押すと last=Beta | clicks=3 です。secondのID確認でBetaは重複しません。
  3. Enable or rebind を繰り返してからAlphaを1回押しても回数は4です。重複登録で増分が倍になることはありません。
  4. Stop demo handler はHandlerをstoppedにし、対象ボタンでも実習の回数と強調が変わらなくなります。Enable or rebindで再開します。
  5. Reset はBetaとAlphaの強調を除き、回数0にしてハンドラーを有効化します。次のAlphaで1から始まります。

動的ボタンと this・event.target

.on() のイベント委譲は存在する#itemsへ登録し、.itemに合う子孫のクリックを処理します。親へ伝わるバブリングを使うため、後から来るBetaに再登録は不要です。途中で伝播が止められると親の処理に届かない場合があります。

通常の関数handleClickのthisは.itemに合うボタンです。Alpha内のspanを押した場合、event.targetはspanでもthisはボタンなので、ボタン全体のクラスを変えられます。このthisを使うとき、安易にアロー関数へ置き換えないでください。ネイティブbuttonなのでフォーカス後のEnterでも実習を動かせます。

必要なハンドラーだけを解除し重複を防ぐ

.off()にはイベントの名前空間と同じ委譲セレクターを渡し、実習の処理だけを解除します。click.demoのclickがイベント名、demoが処理群の名前です。再登録前の.off("click.demo", ".item")により、Enable or rebindを繰り返しても1回だけ処理します。

親の.off()を引数なしで呼ぶと他機能の処理も解除し得ます。必要な機能へ範囲を限定します。Resetは実習で追加した要素・強調・回数を整理してから再び有効化します。

従来の .click() と実行結果を比べる

開発者ツールのConsoleで次の部分コードを実行します。画面へ追加しない2個の一時ボタンで旧形と推奨形を比べ、各1回実行します。

let legacy = 0;
const $old = $("<button>").click(() => legacy++);
$old.click();
console.log(legacy);
let modern = 0;
$("<button>").on("click", () => modern++).trigger("click");
console.log(modern);
1
1

.trigger()は登録済み処理を実行し、バブリングも起こし得ます。実際のユーザー操作を完全には再現しないので、ブラウザーがユーザー操作を必要とする機能まで同じになるとは限りません。実習では通常のボタンの回数とクラスだけを比較します。

反応しなければNetworkのjQuery読み込み、Consoleのエラーと版、セレクター、登録時点の親の存在、Stop状態を確認します。1クリックで複数回動くなら初期化の繰り返しと解除範囲を点検します。