イベントリスナー追加(DOM) — el.addEventListener('click', fn)
ボタンを押す、入力する、スクロールする。こうした「イベント」が起きた瞬間に処理を実行するのがイベントリスナーです。DOM要素に「どのイベントで」「何をするか」を登録します。
基本の使い方
<button id="buy">購入する</button>
<script>
const btn = document.getElementById("buy");
btn.addEventListener("click", () => {
console.log("購入ボタンが押されました");
});
</script>
HTML- 対象要素: まずは対象のDOM要素を取得(
getElementByIdやquerySelector)。 - イベント名:
"click","input","change","keydown","scroll"など。 - ハンドラ: イベント発生時に実行される関数。無名関数でも、外で定義して渡してもOK。
イベントオブジェクトを使う
const input = document.querySelector("#q");
input.addEventListener("input", (e) => {
console.log("現在の値:", e.target.value);
});
JavaScript- e.target: どの要素で起きたか。
- 値取得: 入力系なら
e.target.valueが基本。
よく使うテンプレート集
クリックでクラス切り替え(UI状態変更)
const panel = document.querySelector(".panel");
document.querySelector("#toggle").addEventListener("click", () => {
panel.classList.toggle("open");
});
JavaScriptフォーム送信を防いでAJAX処理に切り替え
const form = document.querySelector("#login");
form.addEventListener("submit", async (e) => {
e.preventDefault(); // 画面遷移の送信を止める
const fd = new FormData(form);
// ここで fetch/axios などで送信
});
JavaScriptキー操作でショートカット
document.addEventListener("keydown", (e) => {
if (e.key === "Escape") closeModal();
});
JavaScriptスクロール位置の計測(throttle併用推奨)
const onScroll = () => {
const y = window.scrollY;
console.log("scrollY:", y);
};
window.addEventListener("scroll", onScroll);
JavaScript実務でのコツ
- ハンドラは関数参照で渡す: 後から解除したいなら「同じ関数」を使う必要があるため、無名関数の乱用は避ける。
function onClick() { /* ... */ }
el.addEventListener("click", onClick);
// 解除: el.removeEventListener("click", onClick);
JavaScript- キャプチャ/パッシブ/オプション: 第3引数に
{ capture, once, passive }を渡せる。- capture: イベント伝播の「捕捉段階」で受け取りたいときに使う。
- passive: スクロールなどで
preventDefaultを使わないならパフォーマンス向上。 - once: 一度だけ実行して自動解除。
el.addEventListener("click", fn, { once: true });
JavaScript- イベント委譲(親でまとめて受ける): 子要素が増減するリストに便利。
const list = document.querySelector(".list");
list.addEventListener("click", (e) => {
const item = e.target.closest(".item");
if (!item) return;
console.log("item clicked:", item.dataset.id);
});
JavaScriptありがちなハマりポイントと対策
- 解除できない(removeEventListenerが効かない): 違う関数インスタンスを渡していることが原因。関数を変数に保持して同一参照で解除。
thisの誤解: ハンドラ内のthisは状況で変わる。安定させるならe.currentTargetや矢印関数でthisを使わない設計に。preventDefaultとstopPropagationの使い分け:preventDefault: 既定動作(リンク遷移、フォーム送信など)を止める。stopPropagation: 伝播(親へバブリング)を止める。多用は慎重に。
- パフォーマンス: スクロールやmousemoveは高頻度。
debounceやthrottleを併用して負荷を下げる。
練習問題(手を動かして覚える)
<button id="a">A</button>
<button id="b">B</button>
<ul class="list">
<li class="item" data-id="1">Item 1</li>
<li class="item" data-id="2">Item 2</li>
</ul>
<script>
// 1) クリックでメッセージ
const a = document.getElementById("a");
function onA() { console.log("A clicked"); }
a.addEventListener("click", onA);
// 2) 一度だけ実行
const b = document.getElementById("b");
b.addEventListener("click", () => console.log("B clicked once"), { once: true });
// 3) 委譲でリストアイテムを検出
const list = document.querySelector(".list");
list.addEventListener("click", (e) => {
const li = e.target.closest(".item");
if (!li) return;
console.log("clicked item id:", li.dataset.id);
});
// 4) 解除してみる
setTimeout(() => {
a.removeEventListener("click", onA);
console.log("Aのクリックハンドラを解除");
}, 3000);
</script>
HTML