Webサイトを作っていて、「ボタンを押したら画面が変わる」「クリックしたら何かが表示される」といった動きを付けたいと思ったことはありませんか?
こうしたインタラクティブな機能を実現するのが、JavaScriptです。
ボタンクリックは、Web開発において最も基本的で重要な操作の一つなんですね。メニューの開閉、フォームの送信確認、画像のスライド表示など、ありとあらゆる場面でボタンクリックのイベント処理が使われています。
JavaScriptを使えば、ページをリロードすることなく、その場で即座に反応する快適なユーザー体験を提供できます。
この記事では、JavaScriptでボタンクリックを処理する様々な方法を、初心者の方にも分かりやすく解説していきます。
基本的な書き方から、実践的なテクニック、よくあるエラーの対処法まで、一緒に学んでいきましょう!
JavaScriptとボタンクリックの基本

まず、JavaScriptがボタンクリックをどのように扱うのか、基本的な仕組みを理解しましょう。
イベントドリブンとは?
JavaScriptはイベントドリブン(イベント駆動)という仕組みで動作します。
これは、「何かが起きたら(イベント)、それに応じた処理を実行する」という考え方です。
代表的なイベント
- click:クリックされたとき
- mouseover:マウスが要素の上に来たとき
- keydown:キーボードが押されたとき
- submit:フォームが送信されたとき
- load:ページの読み込みが完了したとき
ボタンクリックは、この中の「clickイベント」に当たるんですね。
DOMとは?
DOM(Document Object Model)は、HTMLドキュメントをJavaScriptから操作するための仕組みです。
簡単に言えば、HTMLで書かれたボタンやテキストなどの要素を、JavaScriptで「取得したり」「変更したり」「削除したり」できるようにしてくれます。
ボタンクリックを処理するには、まずDOMを使ってボタン要素を取得する必要があるでしょう。
ボタンクリックを処理する基本的な方法
JavaScriptでボタンクリックを処理する方法は、いくつかあります。
方法1:HTML属性にonclickを直接書く
最もシンプルな方法です。
説明
HTMLのボタンタグに直接onclick属性を書き込む方法です。初心者にとって分かりやすいでしょう。
実例
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>ボタンクリック</title>
</head>
<body>
<button onclick="handleClick()">クリックしてね</button>
<script>
function handleClick() {
alert('ボタンがクリックされました!');
}
</script>
</body>
</html>
メリット
- 書き方が簡単
- どの関数が呼ばれるか一目で分かる
デメリット
- HTMLとJavaScriptが混在して管理しづらい
- 複数の処理を割り当てにくい
- 現代的な開発では非推奨
方法2:addEventListener を使う(推奨)
説明addEventListenerメソッドを使って、イベントリスナーを登録する方法です。現代的なJavaScriptではこちらが標準です。
実例
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>ボタンクリック</title>
</head>
<body>
<button id="myButton">クリックしてね</button>
<script>
// ボタン要素を取得
const button = document.getElementById('myButton');
// クリックイベントを登録
button.addEventListener('click', function() {
alert('ボタンがクリックされました!');
});
</script>
</body>
</html>
メリット
- HTMLとJavaScriptを分離できる
- 同じ要素に複数のイベントを登録できる
- イベントの削除も可能
- モダンな書き方
デメリット
- 初心者にはやや複雑に見える
方法3:アロー関数を使う(ES6以降)
説明
アロー関数(=>)を使った、より簡潔な書き方です。
実例
<button id="myButton">クリックしてね</button>
<script>
const button = document.getElementById('myButton');
// アロー関数で簡潔に
button.addEventListener('click', () => {
alert('ボタンがクリックされました!');
});
</script>
アロー関数は見た目がスッキリしますが、thisの扱いが通常の関数と異なる点に注意が必要です。
DOM要素を取得する様々な方法
ボタンを操作するには、まず要素を取得する必要があります。
getElementById
IDを指定して要素を取得します。最も基本的で高速な方法です。
実例
const button = document.getElementById('myButton');
querySelector
CSSセレクターで要素を取得します。柔軟性が高いのが特徴です。
実例
// IDで取得
const button = document.querySelector('#myButton');
// クラスで取得(最初の1つ)
const button = document.querySelector('.btn-primary');
// より複雑なセレクター
const button = document.querySelector('div.container > button');
querySelectorAll
条件に合う要素をすべて取得します。
実例
// すべてのボタンを取得
const buttons = document.querySelectorAll('button');
// 各ボタンにイベントを設定
buttons.forEach(button => {
button.addEventListener('click', () => {
console.log('ボタンがクリックされました');
});
});
getElementsByClassName
クラス名で要素を取得します(複数)。
実例
const buttons = document.getElementsByClassName('btn');
// HTMLCollectionなのでArray.from()で配列に変換
Array.from(buttons).forEach(button => {
button.addEventListener('click', () => {
console.log('クリック!');
});
});
実践的な使用例
実際の開発でよく使われるパターンを紹介します。
例1:カウンターを作る
説明
ボタンをクリックするたびに数字が増えるシンプルなカウンターです。
実例
<div>
<p>カウント: <span id="count">0</span></p>
<button id="incrementBtn">+1</button>
<button id="decrementBtn">-1</button>
<button id="resetBtn">リセット</button>
</div>
<script>
let count = 0;
const countDisplay = document.getElementById('count');
// +1ボタン
document.getElementById('incrementBtn').addEventListener('click', () => {
count++;
countDisplay.textContent = count;
});
// -1ボタン
document.getElementById('decrementBtn').addEventListener('click', () => {
count--;
countDisplay.textContent = count;
});
// リセットボタン
document.getElementById('resetBtn').addEventListener('click', () => {
count = 0;
countDisplay.textContent = count;
});
</script>
例2:要素の表示・非表示を切り替える
説明
ボタンをクリックすると、特定の要素が表示されたり隠れたりする機能です。
実例
<button id="toggleBtn">メッセージを表示/非表示</button>
<div id="message" style="display: none;">
<p>こんにちは!これは隠されていたメッセージです。</p>
</div>
<script>
const toggleBtn = document.getElementById('toggleBtn');
const message = document.getElementById('message');
toggleBtn.addEventListener('click', () => {
if (message.style.display === 'none') {
message.style.display = 'block';
} else {
message.style.display = 'none';
}
});
</script>
例3:クラスの追加・削除
説明
CSSクラスを動的に変更することで、スタイルを切り替えます。
実例
<style>
.highlight {
background-color: yellow;
font-weight: bold;
}
</style>
<p id="text">このテキストをハイライトできます</p>
<button id="highlightBtn">ハイライト切り替え</button>
<script>
const text = document.getElementById('text');
const highlightBtn = document.getElementById('highlightBtn');
highlightBtn.addEventListener('click', () => {
text.classList.toggle('highlight');
});
</script>
classList.toggle()は、クラスがあれば削除、なければ追加する便利なメソッドです。
例4:フォーム送信前の確認
説明
フォームを送信する前に、ユーザーに確認ダイアログを表示します。
実例
<form id="myForm">
<input type="text" name="username" placeholder="ユーザー名" required>
<button type="submit">送信</button>
</form>
<script>
const form = document.getElementById('myForm');
form.addEventListener('submit', (event) => {
// デフォルトの送信動作を止める
event.preventDefault();
// 確認ダイアログを表示
const confirmed = confirm('本当に送信しますか?');
if (confirmed) {
// OKなら送信
form.submit();
}
});
</script>
event.preventDefault()は、デフォルトの動作(この場合はフォーム送信)をキャンセルする重要なメソッドです。
例5:複数のボタンに同じ処理を設定
説明
同じクラスを持つ複数のボタンに、一度に処理を割り当てます。
実例
<button class="alert-btn" data-message="メッセージ1">ボタン1</button>
<button class="alert-btn" data-message="メッセージ2">ボタン2</button>
<button class="alert-btn" data-message="メッセージ3">ボタン3</button>
<script>
const buttons = document.querySelectorAll('.alert-btn');
buttons.forEach(button => {
button.addEventListener('click', function() {
const message = this.dataset.message;
alert(message);
});
});
</script>
data-*属性を使うことで、各ボタンに固有の情報を持たせられます。
イベントオブジェクトを活用する

イベントリスナーの関数には、イベントオブジェクトが自動的に渡されます。
イベントオブジェクトとは?
クリックされた位置、押されたキー、クリックされた要素など、イベントに関する詳細な情報が入っているオブジェクトです。
実例:基本的な使い方
button.addEventListener('click', (event) => {
console.log('クリック位置 X:', event.clientX);
console.log('クリック位置 Y:', event.clientY);
console.log('クリックされた要素:', event.target);
});
event.preventDefault()
デフォルトの動作をキャンセルします。
使用例
- リンクのクリックで遷移させない
- フォームの送信を止める
- 右クリックメニューを無効化
link.addEventListener('click', (event) => {
event.preventDefault();
console.log('リンクの遷移をキャンセルしました');
});
event.stopPropagation()
イベントの伝播(バブリング)を止めます。
実例
<div id="parent" style="padding: 20px; background: lightblue;">
親要素
<button id="child">子要素(ボタン)</button>
</div>
<script>
document.getElementById('parent').addEventListener('click', () => {
console.log('親要素がクリックされました');
});
document.getElementById('child').addEventListener('click', (event) => {
console.log('ボタンがクリックされました');
event.stopPropagation(); // 親要素への伝播を止める
});
</script>
stopPropagation()を使わないと、ボタンをクリックしたときに親要素のイベントも発火してしまいます。
event.target と event.currentTarget
event.target:実際にクリックされた要素event.currentTarget:イベントリスナーが設定されている要素
実例
<button id="myButton">
<span>クリック</span>
</button>
<script>
document.getElementById('myButton').addEventListener('click', (event) => {
console.log('target:', event.target); // <span>が返る(実際にクリックした場所)
console.log('currentTarget:', event.currentTarget); // <button>が返る
});
</script>
イベント委譲(デリゲーション)
動的に追加される要素にもイベントを設定する高度なテクニックです。
問題:後から追加した要素にイベントが効かない
説明
JavaScriptで後から追加した要素には、最初に設定したイベントリスナーが効きません。
問題のあるコード
// 最初からあるボタンにイベント設定
document.querySelectorAll('button').forEach(btn => {
btn.addEventListener('click', () => {
console.log('クリック');
});
});
// 後から追加したボタンには効かない!
const newButton = document.createElement('button');
newButton.textContent = '新しいボタン';
document.body.appendChild(newButton);
解決策:イベント委譲を使う
説明
親要素にイベントを設定し、event.targetで実際にクリックされた要素を判定します。
実例
<div id="buttonContainer">
<button class="dynamic-btn">ボタン1</button>
<button class="dynamic-btn">ボタン2</button>
</div>
<button id="addBtn">ボタンを追加</button>
<script>
// 親要素にイベント委譲
document.getElementById('buttonContainer').addEventListener('click', (event) => {
if (event.target.classList.contains('dynamic-btn')) {
alert(event.target.textContent + 'がクリックされました');
}
});
// ボタンを動的に追加
document.getElementById('addBtn').addEventListener('click', () => {
const container = document.getElementById('buttonContainer');
const newBtn = document.createElement('button');
newBtn.className = 'dynamic-btn';
newBtn.textContent = 'ボタン' + (container.children.length + 1);
container.appendChild(newBtn);
});
</script>
この方法なら、後から追加したボタンでもちゃんとイベントが発火するんですね。
ベストプラクティスと注意点
効率的で保守しやすいコードを書くためのポイントです。
1. DOMContentLoadedを待つ
JavaScriptがHTMLより先に実行されると、要素が見つからずエラーになります。
悪い例
<head>
<script>
// HTMLがまだ読み込まれていないのでエラー!
const button = document.getElementById('myButton');
</script>
</head>
<body>
<button id="myButton">ボタン</button>
</body>
良い例1:scriptをbodyの最後に配置
<body>
<button id="myButton">ボタン</button>
<script>
// この位置ならHTMLが読み込み済み
const button = document.getElementById('myButton');
</script>
</body>
良い例2:DOMContentLoadedイベントを使う
<head>
<script>
document.addEventListener('DOMContentLoaded', () => {
// HTMLの読み込みが完了してから実行
const button = document.getElementById('myButton');
});
</script>
</head>
2. 何度も使う要素は変数に格納する
説明
同じ要素を何度も取得するのは非効率です。一度取得したら変数に保存しましょう。
悪い例
document.getElementById('count').textContent = 0;
document.getElementById('count').style.color = 'red';
document.getElementById('count').classList.add('large');
良い例
const countElement = document.getElementById('count');
countElement.textContent = 0;
countElement.style.color = 'red';
countElement.classList.add('large');
3. 無名関数を使いすぎない
イベントリスナーを削除したい場合、名前付き関数が必要です。
説明
無名関数(直接書いた関数)は後から削除できません。
実例
// 名前付き関数として定義
function handleClick() {
console.log('クリック!');
}
// 追加
button.addEventListener('click', handleClick);
// 後から削除できる
button.removeEventListener('click', handleClick);
4. thisの扱いに注意
通常の関数とアロー関数では、thisの値が異なります。
実例
button.addEventListener('click', function() {
console.log(this); // ボタン要素自身を指す
});
button.addEventListener('click', () => {
console.log(this); // 外側のスコープのthis(通常はwindow)
});
要素自身を参照したい場合は、通常の関数を使うか、event.currentTargetを使いましょう。
5. イベントリスナーの重複登録を避ける
説明
同じ要素に同じイベントを何度も登録すると、複数回実行されてしまいます。
実例
// 悪い例:ループで何度も登録
for (let i = 0; i < 5; i++) {
button.addEventListener('click', () => {
console.log('クリック');
});
}
// ボタンを1回クリックすると5回実行される!
// 良い例:1回だけ登録
button.addEventListener('click', () => {
console.log('クリック');
});
よくあるエラーと解決方法
実装時によく遭遇するエラーとその対処法を紹介します。
エラー1:「Cannot read property ‘addEventListener’ of null」
原因
要素が取得できていません。IDの指定ミスや、JavaScriptが早く実行されすぎている可能性があります。
解決方法
// 要素の存在を確認してから処理
const button = document.getElementById('myButton');
if (button) {
button.addEventListener('click', () => {
console.log('クリック');
});
} else {
console.error('ボタンが見つかりません');
}
エラー2:イベントが複数回発火する
原因
イベントリスナーが重複して登録されています。
解決方法
登録する前に一度削除するか、登録済みかチェックします。
// 一度削除してから登録
button.removeEventListener('click', handleClick);
button.addEventListener('click', handleClick);
エラー3:動的に追加した要素でイベントが動かない
原因
要素が存在しない時点でイベントリスナーを登録しようとしています。
解決方法
イベント委譲を使うか、要素を追加した直後にイベントを設定します。
// 要素を作成
const newButton = document.createElement('button');
newButton.textContent = '新しいボタン';
// イベントを設定
newButton.addEventListener('click', () => {
console.log('クリック');
});
// DOMに追加
document.body.appendChild(newButton);
まとめ
JavaScriptでボタンクリックを処理する方法について解説しました。
イベントリスナーの基本から、実践的なテクニックまで、様々な手法を身につけることで、インタラクティブなWebサイトを作れるようになります。
この記事のポイント
- JavaScriptはイベントドリブンで動作し、clickイベントでボタンクリックを検知する
addEventListenerを使った方法が現代的で推奨される- DOM要素の取得には
getElementByIdやquerySelectorを使う - イベントオブジェクトには、クリック位置や対象要素などの情報が含まれる
preventDefault()でデフォルト動作をキャンセルできるstopPropagation()でイベントの伝播を止められる- イベント委譲を使えば、動的に追加した要素にも対応できる
- DOMの読み込み完了を待ってから要素を取得する
- 通常の関数とアロー関数では
thisの値が異なる - 重複登録や要素の取得ミスに注意する
最初は複雑に感じるかもしれませんが、基本パターンを覚えてしまえば、様々な応用ができるようになります。
この記事のサンプルコードを実際に試しながら、手を動かして学ぶことをおすすめします。
JavaScriptのイベント処理をマスターして、ユーザーが楽しく使えるWebサイトを作りましょう!


コメント