MENU

【JavaScript】イベント処理を解説|Webの基礎

JavaScriptのイベント処理(addEventListener)を解説|Webの基礎
目次

はじめに

前回の記事では、documentオブジェクトを使ったHTML要素の取得・操作方法について解説しました。

今回は、「ボタンがクリックされた」「フォームが送信された」「キーが押された」といった、ユーザーの操作やブラウザの状態変化に反応するイベント処理について解説します。addEventListenerの基本的な使い方から、イベントオブジェクトの活用、フォーム送信の制御、イベントの伝播(バブリング)まで、実務でよく使う内容を中心に紹介します。

イベントとは?

イベントとは、「クリックされた」「入力欄の内容が変わった」「ページの読み込みが完了した」など、ブラウザ上で発生するさまざまな出来事のことです。JavaScriptでは、特定のイベントが発生したときに実行する処理(イベントリスナー)をあらかじめ登録しておくことで、こうした出来事に反応するプログラムを作れます。

【JavaScript】JavaScriptとは?基本を解説」 や 「【JavaScript】documentオブジェクトを解説」 のサンプルでもすでにaddEventListenerを使っていましたが、今回はイベント処理そのものを詳しく掘り下げていきます。

addEventListenerの基本的な使い方

イベントを登録するには、対象の要素に対してaddEventListener()を呼び出します。

要素.addEventListener(イベントの種類, 実行する関数);
const btn = document.getElementById("myBtn");

btn.addEventListener("click", () => {
    console.log("ボタンがクリックされました");
});

第1引数にはイベントの種類を文字列で指定し("click"など)、第2引数には発生時に実行する関数を渡します。

HTMLタグに直接onclick=”…”属性を書いてイベントを登録する方法もありますが、HTML(構造)とJavaScript(振る舞い)が混ざって見通しが悪くなるため、addEventListener()で分離して書くのが基本です。

イベントの解除(removeEventListener)

登録したイベントを解除するにはremoveEventListener()を使いますが、登録時と同じ関数を指定する必要があるため、無名関数(その場で書いた関数)ではなく、名前を付けた関数を使う必要があります。

function handleClick() {
    console.log("クリックされました");
}

btn.addEventListener("click", handleClick);
btn.removeEventListener("click", handleClick); // 登録解除

イベントオブジェクト(event)を活用する

イベントリスナーの関数には、発生したイベントの情報が詰まったイベントオブジェクトが自動的に渡されます。

btn.addEventListener("click", (event) => {
    console.log(event.type);   // "click"(発生したイベントの種類)
    console.log(event.target); // クリックされた要素そのもの
});
プロパティ/メソッド内容
event.targetイベントが実際に発生した要素
event.typeイベントの種類(”click”など)
event.preventDefault()ブラウザの標準動作をキャンセルする
event.stopPropagation()イベントの伝播(バブリング)を止める

preventDefault()stopPropagation()は後述の「フォーム送信の制御」「イベントの伝播」で詳しく扱います。

代表的なイベントの種類

用途別によく使うイベントをまとめました。

分類イベント名発生タイミング
マウスclick要素がクリックされたとき
マウスmouseover / mouseoutマウスが要素に乗った・離れたとき
キーボードkeydown / keyupキーが押された・離されたとき
フォームsubmitフォームが送信されたとき
フォームinput入力欄の内容が変化するたび
フォームchange入力欄・selectの内容が確定したとき
ページloadページ(画像等含む)の読み込みが完了したとき
ページDOMContentLoadedHTMLの読み込み・解析が完了したとき

inputは1文字入力するたびに発生するのに対し、changeは入力欄からフォーカスが外れた時点(確定時)に1回だけ発生します。リアルタイムに反応させたいか、入力確定後でよいかで使い分けましょう。

フォーム送信を制御する(preventDefault)

<form>submitイベントは、通常そのままにしておくとページが再読み込みされます。入力チェックを行ってから送信するかどうかを制御したい場合は、event.preventDefault()でこの標準動作をキャンセルします。

<form id="myForm">
    <input type="text" id="nameInput" placeholder="お名前">
    <p id="errorMsg" style="color: red; display: none;"></p>
    <button type="submit">送信</button>
</form>
const form = document.getElementById("myForm");
const nameInput = document.getElementById("nameInput");
const errorMsg = document.getElementById("errorMsg");

form.addEventListener("submit", (event) => {
    if (nameInput.value.trim() === "") {
        event.preventDefault(); // ページの再読み込みをキャンセル
        errorMsg.textContent = "お名前を入力してください";
        errorMsg.style.display = "block";
    }
});

入力が空の場合はpreventDefault()が呼ばれてページ遷移が止まり、エラーメッセージだけが表示されます。入力があればpreventDefault()は呼ばれず、通常通りフォームが送信されます。

イベントの伝播(バブリング)とイベント委任

子要素で発生したイベントは、親要素、さらにその親……という順に外側へ伝わっていきます。これをバブリングと呼びます。

<div id="parent">
    <button id="child">クリック</button>
</div>
document.getElementById("parent").addEventListener("click", () => {
    console.log("親のリスナーが実行されました");
});

document.getElementById("child").addEventListener("click", () => {
    console.log("子のリスナーが実行されました");
});

ボタン(子)をクリックすると、「子のリスナー」→「親のリスナー」の順に両方実行されます。この伝播を止めたい場合は、子側の処理内でevent.stopPropagation()を呼びます。

このバブリングの仕組みを利用すると、子要素それぞれにイベントを登録せず、親要素1つにまとめて登録することができます。これをイベント委任(イベントデリゲーション)と呼びます。

【JavaScript】documentオブジェクトを解説」のサンプルでは削除ボタンごとにaddEventListenerを登録していましたが、イベント委任を使うと次のように書き換えられます。

const list = document.getElementById("itemList");

list.addEventListener("click", (event) => {
    if (event.target.tagName === "BUTTON") {
        event.target.closest("li").remove();
    }
});

event.targetでクリックされた要素そのものを判定し、条件に合う場合だけ処理を行っています。ボタンが何個増えても親要素に登録した1つのリスナーだけで対応できるため、後から動的に追加した要素にもそのままイベントが効くのが利点です。

実務サンプル(入力チェック+イベント委任)

入力欄への1文字ごとの入力チェックと、リストへの追加・削除をイベント委任で行うサンプルです。

HTML

<input type="text" id="itemInput" placeholder="項目を入力(20文字以内)">
<span id="charCount">0 / 20</span>
<button id="addBtn">追加</button>
<ul id="itemList"></ul>

JavaScript(main.js)

const input = document.getElementById("itemInput");
const charCount = document.getElementById("charCount");
const addBtn = document.getElementById("addBtn");
const list = document.getElementById("itemList");

// inputイベント:入力のたびに文字数を表示
input.addEventListener("input", () => {
    charCount.textContent = `${input.value.length} / 20`;
});

// clickイベント:追加ボタン
addBtn.addEventListener("click", () => {
    const value = input.value.trim();

    if (value === "" || value.length > 20) {
        return;
    }

    const li = document.createElement("li");
    li.textContent = value;

    const delBtn = document.createElement("button");
    delBtn.textContent = "削除";
    li.appendChild(delBtn);

    list.appendChild(li);
    input.value = "";
    charCount.textContent = "0 / 20";
});

// イベント委任:削除ボタンはリスト側でまとめて処理
list.addEventListener("click", (event) => {
    if (event.target.tagName === "BUTTON") {
        event.target.closest("li").remove();
    }
});

inputイベントで文字数のリアルタイム表示、clickイベントで追加、そしてイベント委任で削除ボタンをまとめて処理しています。削除ボタンを個別に登録する必要がないため、コードがシンプルになります。

よくある質問・エラー対処

Q. 同じイベントにaddEventListenerを複数回登録するとどうなる?

→ エラーにはならず、登録した回数分すべての関数が実行されます。同じ処理を意図せず重複登録してしまうと、クリック1回で処理が2回・3回と実行されてしまうため、removeEventListenerで解除するか、登録処理自体が重複して呼ばれていないか見直してください。

Q. removeEventListenerを呼んだのにイベントが解除されない

→ 登録時と解除時でまったく同じ関数を指定する必要があります。() => {...}のような無名関数は毎回別物として扱われるため解除できません。解除する可能性がある場合は、あらかじめ名前を付けた関数を変数に入れて使い回してください。

Q. preventDefault()stopPropagation()の違いがわからない

preventDefault()は「ブラウザの標準動作(フォーム送信によるページ遷移、リンクのクリックによる移動など)」をキャンセルするもの、stopPropagation()は「イベントが親要素へ伝わっていくこと(バブリング)」を止めるものです。役割が異なるため、必要に応じて両方呼ぶこともあります。

おわりに(まとめ)

まとめ

イベント処理を使うと、クリックやフォーム送信、キー入力といったユーザーの操作にJavaScriptで反応できるようになります。

  • ✅ addEventListener(種類, 関数)でイベントを登録する
  • ✅ イベントオブジェクト(event)からevent.targetやevent.typeが取得できる
  • ✅ フォームのsubmitイベントはevent.preventDefault()でページ遷移をキャンセルできる
  • ✅ イベントは子要素から親要素へバブリング(伝播)する
  • ✅ バブリングを利用したイベント委任で、複数要素へのリスナー登録をまとめられる

まずはボタンのclickイベントとevent.target、この2つの組み合わせに慣れることから始めましょう。

次回は、<a>タグを使ったリンクの操作方法について解説予定です。

この記事が、少しでも誰かのお役に立てれば幸いです。

関連記事

当サイトの記事で使用したVBAなどのサンプルをDLできます

この記事のサンプルはありません!

ダウンロードページへは下のカードをクリックすればジャンプできます。
よろしければご利用ください!


【CSS】テキスト関連プロパティについて基本解説|Webの基礎


よかったらシェアしてね!
  • URLをコピーしました!
目次