English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
イベントの伝播は、Webブラウザでイベント「スタック」をトリガーする方法を説明する方法です。
イベントバブルとキャプチャーイベントの伝播の二つのメカニズムであり、同じイベントタイプの二つのハンドラが要素上でアクティブ化された場合に発生する状況を説明しています。
仮にあなたが<div >要素内に<p>要素、ユーザーがクリックしました<p>要素、どの要素の「click」イベントを最初に処理すべきですか?
<div id="div1">キャプチャリング <p id="p1">クリックして</p> </div> <script> document.querySelector("#div1document.querySelector("#p"} document.querySelector("#p1document.querySelector("#p"} </script>テストを見て‹/›
を通じて、イベントはまず最外層の要素でキャプチャーされ、その後内部要素に伝播します。)。addEventListener("click", myFunc, true);キャプチャー
を通じて、イベントはまず最外層の要素でキャプチャーされ、その後内部要素に伝播します。バブルを使用すると、イベントはまず最内層の要素でキャプチャーされ、処理され、その後外層の要素に伝播します。
このaddEventListener()メソッドを使用して、「 useCapture 「useCapture」パラメータは伝播タイプを指定します。以下の文法項では「useCapture」について詳細に説明します。
element.addEventListener(event, listener, useCapture)
「useCapture」のデフォルト値はfalseで、デフォルトでバブル伝播を使用します;trueに設定すると、イベントはキャプチャー伝播を使用します。
イベントの伝播の概念は、DOMの階層構造内で親子関係を持つ複数の要素が同じイベント(例えば、マウスクリック)に対してイベントハンドラを持つ場合に処理するために導入されました。現在の問題は、ユーザーが内部要素をクリックした場合、まずどの要素のclickイベントが処理されるか、すなわち外部要素のclickイベントか内部要素のclickイベントかです。
要素に親要素がある場合(例えば、この例の<p>),ブラウザは2つの異なる段階を実行します-キャプチャー段階とバブル段階。
中でキャプチャー段階:
ブラウザは、要素の最外層の親要素(<html>)がキャプチャー段階でonclickイベントハンドラを登録しているか確認し、あればそのイベントハンドラを実行します。
それから、次に<html>中での次の要素に移動し、同じ操作を実行し、次に移動し、そのようにして順に、実際にクリックされた要素に至ります。
中でバブル段階、その逆です:
ブラウザは、バブル段階で実際にクリックされた要素がその上でonclickイベントハンドラを登録しているかを確認し、あればそのイベントハンドラを実行します。
それから、次の直接の親要素に移動し、次に実行し、そのようにして順に、最終的に<html>要素まで。
主要なブラウザでは、デフォルトですべてのイベントハンドラはバブル段階で登録されます。
キャプチャー段階では、イベントはWindowからDOMツリーを通じてターゲットノードに伝播します。
document.querySelector("div").addEventListener("click", myFunc, true); document.querySelector("p").addEventListener("click", myFunc, true); document.querySelector("a").addEventListener("click", myFunc, true);テストを見て‹/›
ただし、addEventListener()第3引数がtrueに設定された場合のみ、イベントキャプチャが登録されたイベントハンドラと一緒に使用されます。
バブルの段階では、その逆です。この段階では、イベントがターゲット要素からWindowまでDOMツリーを上に伝播します。
document.querySelector("div").addEventListener("click", myFunc); document.querySelector("p").addEventListener("click", myFunc); document.querySelector("a").addEventListener("click", myFunc);テストを見て‹/›
すべてのブラウザがイベントバブルをサポートしており、イベントバブルはすべてのハンドラに適用されます(例えば、onclickやaddEventListener()を使用して登録されている場合でも)。
event.stopPropagation()メソッドを使用して、祖先要素のイベントハンドラに対してイベント情報を通知することを防ぐために、中間でイベント伝播を停止することもできます。
以下の例では、子要素をクリックした場合、親要素上のclickイベントリスナーは実行されません:
document.querySelector("div").addEventListener("click", myFunc); document.querySelector("p").addEventListener("click", myFunc); document.querySelector("a").addEventListener("click", myFunc); function myFunc() { alert("You clicked: ");+ this.tagName); event.stopPropagation(); }テストを見て‹/›
ターゲット要素は生成されたイベントのDOMノードです。
例えば、ユーザーがハイパーリンクをクリックすると、ターゲット要素はハイパーリンクです。
ターゲット要素へのアクセス方法はevent.targetであり、イベント伝播の段階で変更されません。
document.querySelector("div").addEventListener("click", myFunc); document.querySelector("p").addEventListener("click", myFunc); document.querySelector("a").addEventListener("click", myFunc); function myFunc() { alert("target = "); + event.target.tagName); }テストを見て‹/›
特定のイベントには、それに関連するデフォルト操作があります。例えば、リンクをクリックすると、ブラウザがリンクのターゲットに移動し、フォームの送信ボタンをクリックすると、ブラウザがフォームを送信するなどです。このようなデフォルト操作を防止するために、event.preventDefault()メソッドを使用できます。
function myFunc() { event.preventDefault(); }テストを見て‹/›
ただし、デフォルト操作を阻止することでイベントの伝播を阻止することはできません;イベントは通常通りDOMツリーに伝播し続けます。
バブルはイベントデリゲーションを利用できるようにしてくれます。
イベントデリゲートを使用すると、特定のノードにイベントリスナーを追加するのではなく、親オブジェクトにイベントリスナーを追加することができます。
この概念は以下の事実に基づいています:大量のサブ要素のどれか一つをクリックしたときに特定のコードを実行したい場合、親要素にイベントリスナーを設定し、発生したイベントがその親要素にバブルアップするようにすることで、各子要素に個別にイベントリスナーを設定する必要はありません。
この例では、クリック時にメッセージを弹出する場合は、親要素にイベントリスナーを設定できます。<ul>上にクリックイベントリスナーを設定し、リストアイテムを弹出
<ul id="parent-list"> <li id="post-1">Item 1</li> <li id="post-2">Item 2</li> <li id="post-3">Item 3</li> <li id="post-4">Item 4</li> <li id="post-5">Item 5</li> <li id="post-6">Item 6</li> </ul> <script> document.getElementById("parent-list").addEventListener("click", function(event) { if(event.target && event.target.nodeName == "LI") { alert("List item " + event.target.id.replace("post-", "") + " was clicked!"); } }); </script>テストを見て‹/›