イベントバブリングとキャプチャリングを使い分けるポイント
イベントバブリングとキャプチャリングとは?
イベントバブリングは、イベントが発生した要素から、その要素の親要素、さらにその親要素へと、DOMツリーを遡っていくようにイベントハンドラが呼び出される仕組みです。
例えば、以下のようなHTMLコードがあるとします。
<div id="outer">
<div id="inner">
<button id="button">ボタン</button>
</div>
</div>
button
要素をクリックすると、以下の順番でイベントハンドラが呼び出されます。
button
要素inner
要素outer
要素
これは、イベントが最初にbutton
要素で発生し、その後、inner
要素、outer
要素へと伝播していくためです。
イベントキャプチャリングは、イベントバブリングとは逆方向に、DOMツリーを下っていくようにイベントハンドラが呼び出される仕組みです。
イベントキャプチャリングを使用するには、イベントリスナーの第3引数をtrue
に設定する必要があります。
上記の例で、inner
要素のイベントリスナーの第3引数をtrue
に設定すると、以下の順番でイベントハンドラが呼び出されます。
イベントバブリングとキャプチャリングは、それぞれ異なる目的で使用されます。
イベントバブリング
- 多くの場合、イベントバブリングを使用します。
- イベントが発生した要素を特定する必要がない場合に便利です。
- 例えば、ページ全体のどこをクリックしても、同じ処理を実行したい場合などです。
イベントバブリングとキャプチャリングは、JavaScriptにおけるDOMイベント処理の重要な概念です。イベントが発生したとき、どのようにイベントハンドラが呼び出されるかを理解することで、より効率的なコードを書くことができます。
イベントバブリングとキャプチャリングのサンプルコード
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>イベントバブリングとキャプチャリング</title>
</head>
<body>
<div id="outer">
<div id="inner">
<button id="button">ボタン</button>
</div>
</div>
<script>
// イベントバブリング
// outer要素のイベントハンドラ
document.getElementById("outer").addEventListener("click", function() {
console.log("outer要素がクリックされました");
});
// inner要素のイベントハンドラ
document.getElementById("inner").addEventListener("click", function() {
console.log("inner要素がクリックされました");
});
// button要素のイベントハンドラ
document.getElementById("button").addEventListener("click", function() {
console.log("button要素がクリックされました");
});
// イベントキャプチャリング
// outer要素のイベントハンドラ
document.getElementById("outer").addEventListener("click", function(event) {
console.log("outer要素がクリックされました (キャプチャリング)");
}, true);
// inner要素のイベントハンドラ
document.getElementById("inner").addEventListener("click", function(event) {
console.log("inner要素がクリックされました (キャプチャリング)");
}, true);
// button要素のイベントハンドラ
document.getElementById("button").addEventListener("click", function(event) {
console.log("button要素がクリックされました (キャプチャリング)");
}, true);
</script>
</body>
</html>
このコードを実行すると、以下の結果が出力されます。
button要素がクリックされました
inner要素がクリックされました
outer要素がクリックされました
outer要素がクリックされました (キャプチャリング)
inner要素がクリックされました (キャプチャリング)
button要素がクリックされました (キャプチャリング)
outer
要素、inner
要素、button
要素それぞれに、click
イベントのイベントハンドラが設定されています。
イベントハンドラの第3引数をtrue
に設定することで、イベントキャプチャリングを使用しています。
イベントバブリングとキャプチャリングの代替方法
イベント委譲は、イベントバブリングを利用して、親要素でイベント処理を行う手法です。イベントが発生した要素を特定する必要がなく、コードを簡潔に記述できます。
以下のコードは、イベント委譲を使用して、button
要素がクリックされたときに処理を実行する例です。
<div id="outer">
<div id="inner">
<button id="button">ボタン</button>
</div>
</div>
// outer要素のイベントハンドラ
document.getElementById("outer").addEventListener("click", function(event) {
// イベントが発生した要素がbutton要素であれば処理を実行
if (event.target.id === "button") {
console.log("button要素がクリックされました");
}
});
イベントリスナーを直接要素に設定することで、イベントバブリングやキャプチャリングに関係なく、イベント処理を行うことができます。
以下のコードは、button
要素に直接イベントリスナーを設定して、クリックされたときに処理を実行する例です。
<div id="outer">
<div id="inner">
<button id="button">ボタン</button>
</div>
</div>
// button要素のイベントハンドラ
document.getElementById("button").addEventListener("click", function() {
console.log("button要素がクリックされました");
});
イベントの停止
イベント伝播を途中で止めることで、バブリングやキャプチャリングによる不要な処理を防ぐことができます。
以下のコードは、button
要素がクリックされたときに、イベント伝播を停止する例です。
<div id="outer">
<div id="inner">
<button id="button">ボタン</button>
</div>
</div>
// button要素のイベントハンドラ
document.getElementById("button").addEventListener("click", function(event) {
console.log("button要素がクリックされました");
// イベント伝播を停止
event.stopPropagation();
});
イベントバブリングとキャプチャリングは、イベント処理の基本的な手法ですが、状況によっては代替方法が必要になる場合があります。イベント委譲、イベントリスナーの直接設定、イベントの停止などの方法を理解することで、より柔軟なイベント処理を行うことができます。
javascript dom-events event-bubbling