ボタンをクリックしたら文章を変えたい、メニューを開きたいと思っても、「clickとon(‘click’)のどちらを使うの?」「追加したボタンだけ反応しない」と迷うことがありますよね。
jQueryでクリック処理を設定するときは、.on('click', handler)を使います。以前よく使われた.click(handler)は非推奨です。
$('#target-button').on('click', function () {
// クリックされたときの処理
});この記事では、クリック回数の表示、あとから追加した要素へのイベント委譲、FAQアコーディオンを実際に動かしながら、クリックイベントの使い方と動かない原因を解説します。
jQueryのclickイベントとは
clickは、要素がクリック操作で有効化されたときに発生するイベントです。処理を登録しておくと、ボタンを押したあとに文章の変更、クラスの追加、メニューの開閉などを実行できます。
次の図は、ボタン操作から処理が実行されるまでの流れです。

<button>へclickイベントを設定すると、マウスやタッチだけでなく、フォーカスした状態でEnterキーやSpaceキーを押した操作にもブラウザが対応します。クリックできる部品は、見た目だけの<div>ではなく<button type="button">で作りましょう。
clickイベントの基本構文
.on()の第1引数にイベント名'click'、第2引数に実行したい関数を指定します。
$('セレクタ').on('click', function (event) {
// クリックされたときの処理
});eventには、クリックされた場所や対象要素などのイベント情報が入ります。function内のthisは、処理の対象になった要素です。
$('.action-button').on('click', function (event) {
console.log($(this).text());
console.log(event.type); // click
});click()ではなくon(‘click’)を使う
.click(handler)はjQuery 3.3で非推奨になりました。現在のコードは.on('click', handler)で記述します。
// 非推奨の短縮形
$('#target-button').click(function () {
console.log('クリックされました');
});
// 推奨する書き方
$('#target-button').on('click', function () {
console.log('クリックされました');
});.on()なら、イベント委譲、複数イベント、名前空間による解除なども同じ形式で扱えます。既存の.click()が直ちに動かなくなるとは限りませんが、新しく書くコードは.on()へ統一するのが分かりやすいでしょう。
ボタンのクリック回数を表示する
最初に、ボタンを押すたびに数値を1ずつ増やす基本例を作ります。実際に2回クリックした表示が次の画像です。

HTMLでボタンと結果欄を作る
index.htmlへボタンと結果欄を配置します。ボタンのtype="button"は、フォーム内に置いた場合の意図しない送信を防ぐための指定です。
<!doctype html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>クリック回数を表示する例</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="demo">
<p class="demo__label">基本のクリックイベント</p>
<h1>ボタンを押すと回数が増えます</h1>
<p class="lead">クリックされたボタンの処理をjQueryで実行します。</p>
<button id="count-button" type="button">クリックする</button>
<p id="count-result" class="result" aria-live="polite">クリック回数:0回</p>
</main>
<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script src="script.js"></script>
</body>
</html>aria-live="polite"を付けると、数値が変わったことをスクリーンリーダーなどの支援技術へ穏やかに伝えられます。
JavaScriptで数値を更新する
script.jsでは、クリック回数を保存する変数を用意します。クリックされるたびに1を加え、.text()で結果欄を更新します。
let clickCount = 0;
$('#count-button').on('click', function () {
clickCount += 1;
$('#count-result').text(`クリック回数:${clickCount}回`);
});clickCountを関数の外へ置くことで、前回までの回数を保持できます。ページを再読み込みすると変数は0へ戻ります。
あとから追加した要素をクリックできるようにする
ページ表示後に追加されたボタンへ直接イベントを設定しても、追加前の時点では対象要素が存在しません。この場合は、すでに存在する親要素へイベントを設定する「イベント委譲」を使います。
次の例では「項目を追加」を押して作られた項目2もクリックに反応しています。

index.htmlには、追加ボタン、項目を入れる#item-list、結果欄を用意します。
<main class="demo">
<p class="demo__label">イベント委譲の例</p>
<h1>あとから追加した項目も反応します</h1>
<p class="lead">項目を追加してから、追加された項目をクリックしてください。</p>
<button id="add-button" type="button">項目を追加</button>
<div id="item-list" class="item-list">
<button class="item-button" type="button">項目1</button>
</div>
<p id="dynamic-result" class="result" aria-live="polite">
項目を選択してください。
</p>
</main>script.jsでは、#item-listへclickイベントを設定し、第2引数に実際の対象である.item-buttonを指定します。
let itemCount = 1;
$('#add-button').on('click', function () {
itemCount += 1;
const $button = $('<button>')
.addClass('item-button')
.attr('type', 'button')
.text(`項目${itemCount}`);
$('#item-list').append($button);
});
$('#item-list').on('click', '.item-button', function () {
$('.item-button').removeClass('is-selected');
$(this).addClass('is-selected');
$('#dynamic-result').text(`${$(this).text()}を選択しました。`);
});子要素で発生したclickイベントは親要素へ伝わります。この「イベント伝播」を利用するため、あとから追加されたボタンでも#item-listがクリックを受け取り、対象が.item-buttonなら処理を実行できます。
イベント委譲の親要素は、対象を含む最も近い固定要素にします。ページ全体のdocumentへ何でも登録するより、#item-listへ限定したほうが処理を追いやすくなります。
項目の追加に使っているappend()は、次の記事で詳しく解説しています。
クリックで開くFAQアコーディオンを作る
clickイベントの実用例として、質問を押すと回答が開くFAQを作ります。質問部分を<button>にすると、キーボードでも操作できます。

HTMLで質問と回答を関連付ける
aria-controlsには開閉する回答のidを指定します。aria-expandedは閉じているときfalse、開いているときtrueへ変更します。
<main class="demo">
<p class="demo__label">クリックイベントの活用例</p>
<h1>FAQアコーディオン</h1>
<p class="lead">質問をクリックすると回答が開きます。</p>
<div class="accordion">
<div class="accordion__item">
<button
class="accordion__button"
type="button"
aria-expanded="false"
aria-controls="answer-1"
>
<span>jQueryはどこに読み込みますか?</span>
<span aria-hidden="true">+</span>
</button>
<div id="answer-1" class="accordion__panel" hidden>
jQuery本体を先に読み込み、その後に自分のJavaScriptを読み込みます。
</div>
</div>
</div>
</main>クリック時に回答の表示を切り替える
script.jsで現在のaria-expandedを確認し、反対の状態へ切り替えます。回答のhiddenプロパティも同時に更新します。
$('.accordion__button').on('click', function () {
const $button = $(this);
const panelId = $button.attr('aria-controls');
const $panel = $(`#${panelId}`);
const isOpen = $button.attr('aria-expanded') === 'true';
$button.attr('aria-expanded', String(!isOpen));
$button.find('[aria-hidden="true"]').text(isOpen ? '+' : '−');
$panel.prop('hidden', isOpen);
});開閉状態を見た目だけでなくaria-expandedでも伝えると、支援技術からも状態を確認できます。プラス・マイナス記号にはaria-hidden="true"を付け、装飾として扱っています。
複数項目やアニメーションを含むアコーディオンは、次の記事で詳しく解説しています。
3つの例で使うCSS
表示画像では、次のCSSを共通で使っています。style.cssへ記述すると、カード、ボタン、結果欄、アコーディオンの見た目を再現できます。
* {
box-sizing: border-box;
}
body {
margin: 0;
padding: 40px 20px;
color: #172033;
background: #f2f6fc;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}
.demo {
width: min(760px, 100%);
margin: 0 auto;
padding: 36px;
border: 1px solid #d9e2ef;
border-radius: 20px;
background: #fff;
box-shadow: 0 16px 40px rgb(41 70 115 / 10%);
}
.demo__label {
margin: 0 0 8px;
color: #2468d8;
font-weight: 700;
}
h1 {
margin: 0 0 12px;
font-size: clamp(28px, 5vw, 40px);
}
.lead {
margin: 0 0 26px;
color: #536079;
}
button {
padding: 12px 20px;
border: 0;
border-radius: 10px;
color: #fff;
background: #2468d8;
font: inherit;
font-weight: 700;
cursor: pointer;
}
button:hover {
background: #1855b7;
}
button:focus-visible {
outline: 4px solid rgb(36 104 216 / 25%);
outline-offset: 3px;
}
.result {
margin: 22px 0 0;
padding: 18px;
border-left: 6px solid #24a46d;
border-radius: 10px;
color: #176b4b;
background: #eefaf5;
font-weight: 700;
}
.item-list,
.accordion {
display: grid;
gap: 12px;
margin-top: 22px;
}
.item-button,
.accordion__button {
width: 100%;
color: #172033;
background: #eef4ff;
text-align: left;
}
.item-button.is-selected {
color: #fff;
background: #2468d8;
}
.accordion__button {
display: flex;
justify-content: space-between;
}
.accordion__panel {
padding: 18px;
border-left: 4px solid #2468d8;
background: #f8faff;
}
.accordion__panel[hidden] {
display: none;
}
@media (max-width: 560px) {
body {
padding: 20px 12px;
}
.demo {
padding: 24px 18px;
}
}リンクのクリックを処理する
リンクには「指定URLへ移動する」という既定動作があります。クリック後にページを移動させたくない場合は、イベントのpreventDefault()を呼び出します。
$('.modal-link').on('click', function (event) {
event.preventDefault();
$('#modal').removeAttr('hidden');
});単に処理を実行するだけならリンクではなくボタンを使います。別ページへ移動する意味があるときだけ<a href="...">を選びましょう。
クリックをJavaScriptから実行する
.trigger('click')を使うと、登録済みのclick処理をJavaScriptから実行できます。テストや、別の操作から同じ処理を呼びたい場合に利用します。
$('#target-button').on('click', function () {
console.log('クリック処理を実行しました');
});
$('#target-button').trigger('click');非推奨の引数なし.click()で発火させるのではなく、目的が明確な.trigger('click')を使ってください。
clickが動かない・2回動くときの確認ポイント
HTMLより先にイベントを設定している
対象要素が作られる前に$('#target-button')を実行すると、イベントを設定できません。script.jsを</body>直前で読み込むか、DOMの準備後に実行します。
$(function () {
$('#target-button').on('click', function () {
console.log('クリックされました');
});
});セレクタが一致していない
id="target-button"は$('#target-button')、class="target-button"は$('.target-button')で選択します。#と.を取り違えていないか確認してください。
あとから追加した要素へ直接設定している
動的に追加する要素には、先に存在する親要素からイベント委譲します。$('#item-list').on('click', '.item-button', handler)の形を使いましょう。
同じイベントを複数回登録している
クリック1回で処理が2回動く場合は、script.jsを重複して読み込んでいないか、同じ初期化関数を繰り返し実行していないか確認します。
再初期化が必要な部品では、イベント名に名前空間を付けてから解除・再登録すると重複を防げます。
$('#target-button')
.off('click.counter')
.on('click.counter', function () {
console.log('1回だけ実行します');
});親と子の両方に処理がある
clickイベントは子要素から親要素へ伝播します。親と子の両方にイベントがあると、両方の処理が実行されます。まずは意図した動きか確認し、必要な場合だけevent.stopPropagation()で親への伝播を止めます。
矢印関数でthisを使っている
変更対象をthisで取得する場合はfunction () {}を使います。矢印関数を使う場合はevent.currentTargetから取得してください。
$('#target-button').on('click', (event) => {
$(event.currentTarget).addClass('is-active');
});.on()の仕組みや解除方法を詳しく確認したい場合は、次の記事も参考にしてください。
jQueryのclickについてよくある質問
クリック処理を1回だけ実行できますか?
.one('click', handler)を使うと、最初の1回だけ処理を実行し、その後は自動でイベントが解除されます。
$('#welcome-button').one('click', function () {
console.log('最初の1回だけ表示します');
});ダブルクリックを検知できますか?
.on('dblclick', handler)で検知できます。ただし、スマートフォンでは操作が分かりにくく、誤操作も起こりやすいため、重要な操作は通常のクリックで実行できる設計がおすすめです。
buttonとdivのどちらへ設定すればよいですか?
ユーザーが操作する部品には<button>を使います。ブラウザ標準のキーボード操作とフォーカスを利用でき、役割も支援技術へ伝わります。
まとめ
jQueryでクリック処理を設定するときは、非推奨の.click()ではなく.on('click', handler)を使います。処理内のthisやevent.currentTargetから、対象要素を取得できます。
あとから追加する要素には、近い固定の親要素からイベント委譲します。操作部品を<button>で作り、フォーカス表示やaria-expandedも整えると、マウス以外でも使いやすいクリック処理になります。
