【JS応用|実務向け】実務で差がつく!Event.targetを使いこなすためのイベント委譲テクニック

導入

フロントエンド開発において、イベントハンドリングは避けて通れません。特に、リスト要素や動的に生成されるDOMに対して一つずつイベントリスナーを登録するのは、メモリの無駄遣いであり、パフォーマンス低下の原因にもなります。本記事では、Event.targetを活用した「イベント委譲(Event Delegation)」の手法を解説します。これを習得することで、コードの保守性が高まり、動的なDOM操作にも柔軟に対応できるようになります。

基礎知識

Event.targetとは、イベントが発生した「まさにその要素」を指すプロパティです。これに対し、Event.currentTargetは「イベントリスナーが登録されている要素」を指します。
イベントは親要素に向かって伝播する「バブリング」という性質を持っています。この仕組みを利用し、子要素それぞれにリスナーを付けるのではなく、親要素に一つだけリスナーを登録し、Event.targetを使って「どの要素がクリックされたか」を判定するのがイベント委譲です。

実装/解決策

イベント委譲を実装する際は、Event.targetが期待する要素(例えばボタンやリスト項目)であるかを確認する処理が重要です。具体的には、matchesメソッドを使ってターゲットを検証します。これにより、特定のクラスやタグを持つ要素のみに反応させることが可能です。

サンプルプログラム

以下のコードは、親となるul要素に一つだけイベントを登録し、動的に追加されたli要素のクリックも検知する実装例です。

// HTML構造: <ul id="list"><li>項目1</li></ul>

const list = document.getElementById('list');

list.addEventListener('click', (event) => {
  // event.targetは「実際にクリックされた要素」を取得
  const target = event.target;

  // matchesメソッドで、特定のセレクタに一致するか確認する
  // これにより、ul自体をクリックした場合は無視できる
  if (target.matches('li')) {
    console.log('クリックされた項目:', target.textContent);
    
    // 特定の処理を実行
    target.style.backgroundColor = '#f0f0f0';
  }
});

// 新しい要素を動的に追加しても、親のリスナーが検知してくれる
const newLi = document.createElement('li');
newLi.textContent = '項目2';
list.appendChild(newLi);

応用・注意点

現場で活用する際の最大の注意点は、「子要素の中にさらに要素がある場合」です。例えば、liの中にspanタグが含まれていると、Event.targetはspanを指してしまい、matches(‘li’)がfalseになることがあります。
これを回避するには、closestメソッドを使用するのがベストプラクティスです。

修正案:
if (target.closest(‘li’)) { … }

これを使うと、クリックされた要素自体、もしくはその親要素を遡って条件に合うものを探してくれるため、入れ子構造に非常に強くなります。また、イベントハンドラ内では必ず「どの要素がアクションの起点か」を明確に意識し、無駄なリスナーを削除する癖をつけることで、メモリリークを防ぐ堅牢なアプリケーション構築が可能になります。

タイトルとURLをコピーしました