イベント処理は、ユーザーの操作(クリック、入力、スクロールなど)に応じてJavaScriptのコードを実行する仕組みです。インタラクティブなWebページを作るための基本技術で、DOM操作と並んでフロントエンド開発の必須スキルです。
基本的な使い方
addEventListener()で要素にイベントリスナーを登録します。イベントが発生すると、指定したコールバック関数が実行されます。
JavaScript
// イベントリスナーの登録
const button = document.querySelector("#myButton");
button.addEventListener("click", function(event) {
console.log("ボタンがクリックされました");
console.log("対象要素:", event.target.tagName);
});
// アロー関数で書く場合
button.addEventListener("click", (e) => {
console.log("クリック位置:", e.clientX, e.clientY);
});
// イベントリスナーの削除
function handleClick() {
console.log("1回だけ実行");
button.removeEventListener("click", handleClick);
}
button.addEventListener("click", handleClick);
// onceオプション(1回だけ実行してから自動削除)
button.addEventListener("click", () => {
console.log("1回だけ実行(once)");
}, { once: true });実行結果
ボタンがクリックされました
対象要素: BUTTON
クリック位置: 150 200
1回だけ実行
1回だけ実行(once)よく使うイベントの種類
マウス、キーボード、フォーム、ウィンドウなど、さまざまなイベントを処理できます。
JavaScript
// マウスイベント
element.addEventListener("click", handler); // クリック
element.addEventListener("dblclick", handler); // ダブルクリック
element.addEventListener("mouseenter", handler); // マウスが乗った
element.addEventListener("mouseleave", handler); // マウスが離れた
// キーボードイベント
document.addEventListener("keydown", (e) => {
console.log("キー:", e.key, "コード:", e.code);
if (e.key === "Escape") console.log("Escキーが押されました");
if (e.ctrlKey && e.key === "s") {
e.preventDefault(); // ブラウザのデフォルト動作を抑止
console.log("Ctrl+S: 保存処理を実行");
}
});
// フォームイベント
const input = document.querySelector("input");
input.addEventListener("input", (e) => {
console.log("入力値:", e.target.value);
});
input.addEventListener("change", (e) => {
console.log("確定値:", e.target.value);
});
input.addEventListener("focus", () => console.log("フォーカス"));
input.addEventListener("blur", () => console.log("フォーカス外れた"));
// フォーム送信
const form = document.querySelector("form");
form.addEventListener("submit", (e) => {
e.preventDefault(); // ページ遷移を防止
const formData = new FormData(form);
console.log("送信データ:", Object.fromEntries(formData));
});実行結果
キー: Escape コード: Escape
Escキーが押されました
入力値: テスト
確定値: テスト入力
フォーカス
フォーカス外れたイベントの委任(Event Delegation)
イベントの委任は、子要素のイベントを親要素で一括して処理するパターンです。動的に追加される要素にも対応でき、パフォーマンスも向上します。
JavaScript
// イベントの委任(Event Delegation)
const todoList = document.querySelector("#todo-list");
// 親要素にリスナーを1つだけ登録
todoList.addEventListener("click", (e) => {
// クリックされた要素がボタンか判定
if (e.target.classList.contains("delete-btn")) {
const item = e.target.closest("li");
item.remove();
console.log("項目を削除しました");
}
if (e.target.classList.contains("complete-btn")) {
const item = e.target.closest("li");
item.classList.toggle("completed");
console.log("完了状態を切り替えました");
}
});
// 動的に追加された要素にも自動で対応
function addTodo(text) {
const li = document.createElement("li");
li.innerHTML = `
${text}
`;
todoList.appendChild(li);
}実践的な活用例
JavaScript
// デバウンス付きの検索入力
function debounce(fn, delay) {
let timer;
return function(...args) {
clearTimeout(timer);
timer = setTimeout(() => fn.apply(this, args), delay);
};
}
const searchInput = document.querySelector("#search");
searchInput.addEventListener("input", debounce((e) => {
console.log("検索:", e.target.value);
}, 300));
// スクロール位置の監視
window.addEventListener("scroll", debounce(() => {
const scrollY = window.scrollY;
const header = document.querySelector("header");
if (scrollY > 100) {
header.classList.add("scrolled");
} else {
header.classList.remove("scrolled");
}
}, 50));
// カスタムイベント
const customEvent = new CustomEvent("userAction", {
detail: { action: "login", user: "田中" }
});
document.addEventListener("userAction", (e) => {
console.log("カスタムイベント:", e.detail);
});
document.dispatchEvent(customEvent);実行結果
カスタムイベント: { action: "login", user: "田中" }イベントのバブリング
イベントは子要素から親要素に向かって伝播します(バブリング)。event.stopPropagation()で伝播を止めることができます。イベント委任はこのバブリングを利用した技法です。
注意点
addEventListener()で登録したリスナーは、不要になったらremoveEventListener()で削除してください。特にSPAでは、コンポーネント破棄時にリスナーを残すとメモリリークの原因になります。アロー関数で登録したリスナーは参照が異なるため削除できない点にも注意が必要です。
まとめ
addEventListener()でイベントリスナーを登録event.preventDefault()でデフォルト動作を抑止- イベント委任で動的要素にも対応し、パフォーマンスを向上
- デバウンスで高頻度イベントの処理を最適化
- 不要なリスナーは
removeEventListener()で削除する