はじめに
DOMイベントは、ユーザーの操作(クリック、キー入力、ドラッグなど)に反応してWebページに動きを与える仕組みです。この記事では、イベントの基本的な扱い方から実践的なテクニックまでを解説します。
イベントの設定方法:3つのアプローチ
JavaScriptでイベントを設定する方法は主に3つあります。それぞれの特徴を見ていきましょう。
1. HTMLインライン方式(非推奨)
HTML要素の属性として直接JavaScriptを記述する方法です。
<button onclick="alert('クリックされました')">クリックしてね</button>
<button onclick="alert('クリックされました')">クリックしてね</button>
<button onclick="alert('クリックされました')">クリックしてね</button>
この方式は同じ処理を何度も書く必要があり、コードの保守性が低いため推奨されません。HTMLとJavaScriptの責任を分離する観点からも避けるべき方法です。
2. onclickプロパティ(非推奨)
JavaScriptからHTML要素のプロパティとしてイベントを設定する方法です。
<button id="myButton">クリックしてね</button>
<script>
const button = document.getElementById("myButton");
button.onclick = function () {
alert("クリックされました");
};
</script>
インライン方式よりは改善されていますが、1つの要素に対して1つのイベントハンドラしか設定できないという制限があります。
3. addEventListenerメソッド(推奨)
現代的なイベント処理の標準的な方法です。
<button id="myButton">クリックしてね</button>
<script>
const button = document.getElementById("myButton");
button.addEventListener("click", function () {
alert("クリックされました");
});
</script>
addEventListenerのメリット
- 同じ要素に複数のイベントリスナーを追加できる
- イベントの削除が容易(removeEventListenerを使用)
- イベントフェーズ(キャプチャ/バブリング)を制御できる
イベントリスナーの基礎知識
thisキーワードの扱い
イベントリスナー内でのthisは、イベントが発生した要素を参照します。
<button id="myButton">クリックしてね</button>
<script>
const button = document.getElementById("myButton");
button.addEventListener("click", function () {
alert(this.id); // 'myButton'と表示される
});
</script>
ただし、アロー関数を使用した場合、thisは外側のスコープを参照するため注意が必要です。
// 通常の関数:thisはbutton要素を指す
button.addEventListener("click", function () {
console.log(this); // <button id="myButton">
});
// アロー関数:thisは外側のスコープを指す
button.addEventListener("click", () => {
console.log(this); // Windowオブジェクトなど
});
イベントオブジェクトとは
イベントが発生すると、イベントの詳細情報を含むオブジェクトが自動的に生成されます。このオブジェクトには、クリック座標、押されたキー、イベントの発生元など様々な情報が含まれています。
<button id="myButton">クリックしてね</button>
<script>
const button = document.getElementById("myButton");
button.addEventListener("click", function (event) {
console.log(event.clientX); // クリックされたX座標
console.log(event.clientY); // クリックされたY座標
});
</script>
さまざまなイベントの種類
クリックイベント
最も基本的なイベントです。マウスクリックやタップ操作で発火します。
element.addEventListener("click", function (event) {
// クリック時の処理
});
キーボードイベント
キーボードの操作を検知するイベントです。テキスト入力やショートカットキーの実装に使用します。
<input type="text" id="myInput" placeholder="ここにタイプしてね" />
<script>
const input = document.getElementById("myInput");
input.addEventListener("keydown", function (event) {
console.log(event.key); // 押されたキーの名前(例:"a", "Enter")
console.log(event.keyCode); // 押されたキーのコード(非推奨)
console.log(event.ctrlKey); // Ctrlキーが押されているか
});
</script>
主なキーボードイベント
-
keydown: キーが押された瞬間 -
keyup: キーが離された瞬間 -
keypress: キーが押されて文字が入力された時(非推奨)
フォームイベント
フォームの送信時に発火するイベントです。デフォルトではページ遷移が発生しますが、preventDefaultメソッドでこれを防ぐことができます。
<form id="myForm">
<input type="text" name="username" placeholder="ユーザー名" />
<button type="submit">送信</button>
</form>
<script>
const form = document.getElementById("myForm");
form.addEventListener("submit", function (event) {
event.preventDefault(); // フォームのデフォルト動作を防ぐ
alert("フォームが送信されました");
});
</script>
inputイベント
ユーザーが入力フィールドの内容を変更したときに発生するイベントです。リアルタイムで入力内容を取得できます。
<input type="text" id="myInput" placeholder="ここにタイプしてね" />
<script>
const input = document.getElementById("myInput");
input.addEventListener("input", function (event) {
console.log(event.target.value); // 現在の入力内容をリアルタイムで表示
});
</script>
検索フィールドの自動補完やリアルタイムバリデーションなどに活用できます。
発展的なトピック
イベントバブリング
イベントバブリングとは、子要素で発生したイベントが親要素へと伝播していく現象です。「バブル(泡)が水中から浮上していく」というイメージで覚えておくと分かりやすいですね。
<div id="parent" style="padding: 20px; border: 1px solid black;">
親要素
<button id="child">子要素</button>
</div>
<script>
const parent = document.getElementById("parent");
const child = document.getElementById("child");
parent.addEventListener("click", function () {
alert("親要素がクリックされました");
});
child.addEventListener("click", function (event) {
alert("子要素がクリックされました");
event.stopPropagation(); // バブリングを停止
});
</script>
event.stopPropagation()を使用することで、イベントの伝播を停止できます。
イベントデリゲーション
ページ読み込み後に動的に生成される要素に対してもイベントを適用したい場合、イベントデリゲーションが有効です。親要素にイベントリスナーを設定し、実際のターゲット要素を判定して処理を行います。
<ul id="itemList">
<li>アイテム 1</li>
<li>アイテム 2</li>
</ul>
<button id="addItem">アイテムを追加</button>
<script>
const itemList = document.getElementById("itemList");
const addItemButton = document.getElementById("addItem");
// 親要素(ul)にイベントリスナーを設定
itemList.addEventListener("click", function (event) {
if (event.target.tagName === "LI") {
alert(event.target.textContent + " がクリックされました");
}
});
// 動的に要素を追加
addItemButton.addEventListener("click", function () {
const newItem = document.createElement("li");
newItem.textContent = "新しいアイテム";
itemList.appendChild(newItem);
});
</script>
イベントデリゲーションのメリット
- 動的に追加された要素にも自動的にイベントが適用される
- 多数の要素に個別にイベントリスナーを設定する必要がなく、パフォーマンスが向上する
- コードの保守性が高まる
まとめ
この記事では、DOMイベントの基礎から実践的なテクニックまでを解説しました。
重要なポイント
- イベント設定には
addEventListenerを使用する - イベントオブジェクトから様々な情報を取得できる
- イベントバブリングの仕組みを理解する
- 動的要素にはイベントデリゲーションを活用する
これらの知識を活用して、よりインタラクティブで使いやすいWebページを作成していきましょう。