イベント処理——利用者の操作に反応する
レッスン7:イベント処理——利用者の操作に反応する
このレッスンで学ぶこと
- イベントの考え方を理解する
- addEventListenerでイベントを登録できる
- click・input・submitといった主要なイベントを使える
- フォームの入力値を取得して処理に使える
- preventDefaultでデフォルト動作を抑制できる
レッスン6では、JavaScriptでHTMLの中身を書き換える「DOM操作」を学びました。ただし、ページが読み込まれた瞬間に1回だけ書き換わる仕組みでした。このレッスンでは、利用者の操作(クリック・入力・送信など)に反応してDOMを変える「イベント処理」を学びます。これでようやく、動的なWebページの核心が完成します。
イベントとは
イベントは、ブラウザで起きるさまざまな出来事を指す言葉です。
- ボタンがクリックされた
- 入力欄に文字が入力された
- フォームが送信された
- マウスが要素の上に乗った
- ページの読み込みが完了した
これらは全部「イベント」です。JavaScriptは、これらのイベントが起きたとき呼び出される処理(イベントハンドラ)を登録できます。
💡 ポイント 「イベントが起きたら〜する」という構造で書くプログラミングを「イベント駆動」と呼びます。Webページに限らず、スマホアプリ、ゲーム、デスクトップアプリなど、利用者が操作するソフトウェアの多くがこの仕組みで動いています。
addEventListener——イベントを登録する
イベントハンドラを登録する基本のメソッドが addEventListener です。
要素.addEventListener("イベント名", 実行する関数);
具体例で見てみましょう。レッスン6で index.html に追加したデモ用の領域には、ボタンが2つあります。#changeButton をクリックしたときに、メッセージを書き換える処理を書いてみます。
main.js の最後(レッスン6で追加したコードの後)に、次を追加してください。
const changeButton = document.querySelector("#changeButton");
changeButton.addEventListener("click", () => {
message.textContent = "ボタンが押されました!";
});
- 1行目:ボタン要素を取得
- 3行目:「click」イベントが起きたら、中の関数を実行する登録
message はレッスン6で取得した <p id="message"> です。同じ main.js 内なので再利用できます。
保存してブラウザを再読み込みし、「テキストを変更」ボタンを押してみてください。<p id="message"> の中身が「ボタンが押されました!」に変わるはずです。何度も押せば何度も書き換わりますが、同じ文字なので変化がわかりません。
カウンターを実装する
もう少し変化がわかりやすい例を作ります。「カウンター追加」ボタンを押すたびに、<span id="count"> の中の数字が増える処理です。
main.js の続きに、次のコードを追加してください。
const incrementButton = document.querySelector("#incrementButton");
const countElement = document.querySelector("#count");
let counter = 0;
incrementButton.addEventListener("click", () => {
counter = counter + 1;
countElement.textContent = counter;
});
ポイントは3つです。
counterという変数で現在のカウントを保持する(letで宣言。後で値を変えるため)- クリックされるたびに
counterを1増やす - その値を
countElement.textContentに反映する
保存してブラウザを再読み込みし、「カウンター追加」ボタンを押すと、「クリック数:0」が「1」「2」「3」と増えていきます。
💡 ポイント 「変数で状態を管理し、イベントが起きたら状態を更新して、画面に反映する」——このパターンが、JavaScriptでWebアプリを作るときの最も基本となる流れです。レッスン8のToDoリストでもまったく同じ構造を使います。
このパターンを図にすると、次のような循環構造になります。
flowchart LR
U[ユーザーの操作] --> E[イベント発火]
E --> S[状態を更新]
S --> R[画面に反映]
R --> U
ユーザーが操作するたびにこのループがぐるりと一周回り、そのたびに画面が変わります。「画面が変わる」のは「状態が変わったから」であり、JavaScriptがやっているのは突き詰めれば状態の管理と反映だけ、と捉えると見通しがよくなります。
主要なイベント
イベントには非常にたくさんの種類があります。本レッスンでは入門段階で押さえておきたい主要なものを紹介します。
| イベント名 | 起きるタイミング |
|---|---|
click |
要素がクリックされた |
input |
入力欄の値が変化した(文字を1文字打つたびに発生) |
change |
入力欄の値が確定した(フォーカスが外れたとき) |
submit |
フォームが送信されようとしている |
mouseover |
マウスが要素の上に乗った |
mouseout |
マウスが要素から離れた |
keydown |
キーボードのキーが押された |
load |
ページの読み込みが完了した |
入門段階で特によく使うのは click と input と submit です。本レッスンではこの3つを実習します。
inputイベント——入力欄からのリアルタイム反映
入力欄に入力された値をリアルタイムで反映する例を作ります。デモ領域に入力欄を1つ追加します。
index.html の .js-demo セクションに、次のHTMLを追加してください。
<p>名前を入力すると、リアルタイムで挨拶文が表示されます。</p>
<input type="text" id="nameInput" placeholder="お名前">
<p id="greeting">こんにちは、ゲストさん!</p>
そして main.js の最後に、次のコードを追加します。
const nameInput = document.querySelector("#nameInput");
const greeting = document.querySelector("#greeting");
nameInput.addEventListener("input", () => {
const name = nameInput.value;
if (name === "") {
greeting.textContent = "こんにちは、ゲストさん!";
} else {
greeting.textContent = `こんにちは、${name}さん!`;
}
});
保存してブラウザを再読み込みし、入力欄に文字を入力してみてください。1文字打つたびに、下の挨拶文がリアルタイムで切り替わります。
入力欄の値は 要素.value で取得します。textContent ではなく value を使うのがポイントです。
🔰 初学者の方へ
inputイベントは「1文字打つたび」に発生します。これに対してchangeイベントは「入力が確定したとき(フォーカスが外れた瞬間など)」に発生します。リアルタイム反映ならinput、確定時の処理ならchange、と使い分けます。
submitイベントとpreventDefault
フォームが送信されると、ブラウザは標準の動作としてページを再読み込みします。これを止めて、JavaScriptで自前の処理をしたいときに使うのが preventDefault です。
例として、簡単なお問い合わせフォーム風の処理を作ります。
index.html の .js-demo セクションに、次のHTMLを追加してください。
<form id="contactForm">
<p>
<label>メッセージ:</label>
<input type="text" id="messageInput" required>
</p>
<button type="submit">送信</button>
</form>
<p id="formResult"></p>
main.js の最後に、次を追加します。
const contactForm = document.querySelector("#contactForm");
const messageInput = document.querySelector("#messageInput");
const formResult = document.querySelector("#formResult");
contactForm.addEventListener("submit", (event) => {
event.preventDefault();
const text = messageInput.value;
formResult.textContent = `送信内容:「${text}」を受け付けました。`;
messageInput.value = "";
});
ここでのポイントは2つです。
event.preventDefault()で、ブラウザの「フォーム送信時にページを再読み込みする」というデフォルト動作を止める- 引数
eventは、イベントの情報を持つオブジェクト。addEventListenerの関数は自動的にこれを受け取れる
保存してブラウザを再読み込みし、入力欄にメッセージを入れて「送信」ボタンを押すと、ページは再読み込みされず、「送信内容:「○○」を受け付けました。」と表示されます。
💡 ポイント 実際のお問い合わせフォームでは、
preventDefaultで標準動作を止めた上で、JavaScriptからサーバーにデータを送る処理を書きます。サーバーとの通信は本コースでは扱いませんが、preventDefaultの使い方は実務でも頻出するので覚えておきましょう。
イベント処理の実習を整理する
ここまでの実習で書いたコードを、main.js の最後の部分にまとめておきます。次の構造になっているはずです。
// レッスン6で書いたコード(要素の取得とDOM操作)
const message = document.querySelector("#message");
message.textContent = "JavaScriptでHTMLを書き換えました!";
message.classList.add("highlight");
const count = document.querySelector("#count");
count.textContent = "50";
const heading = document.querySelector("h1");
heading.style.color = "#2980b9";
// レッスン7で追加:ボタンクリックイベント
const changeButton = document.querySelector("#changeButton");
changeButton.addEventListener("click", () => {
message.textContent = "ボタンが押されました!";
});
// カウンター
const incrementButton = document.querySelector("#incrementButton");
const countElement = document.querySelector("#count");
let counter = 0;
incrementButton.addEventListener("click", () => {
counter = counter + 1;
countElement.textContent = counter;
});
// 入力欄からのリアルタイム反映
const nameInput = document.querySelector("#nameInput");
const greeting = document.querySelector("#greeting");
nameInput.addEventListener("input", () => {
const name = nameInput.value;
if (name === "") {
greeting.textContent = "こんにちは、ゲストさん!";
} else {
greeting.textContent = `こんにちは、${name}さん!`;
}
});
// フォーム送信のpreventDefault
const contactForm = document.querySelector("#contactForm");
const messageInput = document.querySelector("#messageInput");
const formResult = document.querySelector("#formResult");
contactForm.addEventListener("submit", (event) => {
event.preventDefault();
const text = messageInput.value;
formResult.textContent = `送信内容:「${text}」を受け付けました。`;
messageInput.value = "";
});
これで4種類のイベント(クリック2種・入力・送信)を扱う実装が揃いました。動的に変わるWebページの一通りのパターンを、自分の手で書いた状態です。
⚠️ 注意
countという変数名を、レッスン6では<span id="count">の取得名として使っていました。レッスン7では別の意味で使わないよう、カウンター用の変数はcounter、要素はcountElementと分けてあります。同じスコープで同じ名前の変数を二重に宣言するとエラーになるため、変数名の重複には気を付けましょう。
まとめ
このレッスンでは、以下のことを学びました。
- イベントは「クリック」「入力」「送信」などブラウザで起きる出来事
addEventListener("イベント名", 関数)でイベントハンドラを登録する- 入門段階でよく使うイベントは
click・input・submit - 入力欄の値は
valueプロパティで取得する event.preventDefault()でブラウザのデフォルト動作(フォーム送信時の再読み込みなど)を止められる- 「変数で状態を管理→イベントで状態を更新→画面に反映」がWebアプリの基本パターン
次のレッスンでは、これまでの全知識を組み合わせて、ToDoリストの小さなWebアプリを実装します。コースの締めくくりとして、JavaScriptがブラウザ以外でも動くこと(Node.jsなど)も紹介し、次の学習ステップを案内します。
確認クイズ
このレッスンの理解度をチェックしましょう。