[解決済み] イベントバブリング、キャプチャーとは何ですか?
質問
イベントバブリングとキャプチャーの違いは何ですか?バブリングとキャプチャーを使い分けるべきタイミングは?
どのように解決するのですか?
イベントバブリングとキャプチャーとは、HTML DOM API におけるイベントの伝搬方法のひとつで、ある要素で発生したイベントが別の要素の内部で発生し、両方の要素がそのイベントに対するハンドルを登録した場合に発生するものです。イベント伝播のモードは の順にイベントを受け取ります。 .
バブリングでは、イベントはまず最も内側の要素で捕捉・処理され、その後、外側の要素に伝搬されます。
キャプチャリングでは、イベントはまず一番外側の要素で捕捉され、内側の要素に伝搬されます。
Capturingはtricklingとも呼ばれ、伝搬の順番を覚えるのに役立ちます。
<ブロッククオートぽろぽろ落ちる、泡立つ
その昔、Netscapeはイベントキャプチャを、Microsoftはイベントバブリングを提唱していました。どちらもW3Cの一部です Document Object Model イベント 規格(2000年)に準拠しています。
IE < 9 は イベントバブリングのみ 一方、IE9+やすべての主要なブラウザは両方をサポートしています。一方 イベントバブリングのパフォーマンスは若干低下する可能性があります。 複雑なDOMの場合
を使用することができます。
addEventListener(type, listener, useCapture)
を使用して、バブリング (デフォルト) またはキャプチャーモードのイベントハンドラを登録します。キャプチャリングモードを使用するには、第三引数に
true
.
使用例
<div>
<ul>
<li></li>
</ul>
</div>
上記の構成で、クリックイベントが
li
要素を使用します。
キャプチャリングモデルでは、イベントは
div
のクリックイベントハンドラ)。
div
が最初に起動し)、次に
ul
そして最後にターゲット要素で。
li
.
バブリングモデルでは、その逆で、イベントは最初に
li
で、次に
ul
で、最後に
div
要素を使用します。
詳しくは
- イベントオーダー on QuirksMode
- addEventListener MDN上
- イベント詳細 on QuirksMode
下の例では、ハイライトされた要素のいずれかをクリックすると、イベント伝播フローの捕捉フェーズが最初に発生し、その後にバブリングフェーズが発生することがわかります。
var logElement = document.getElementById('log');
function log(msg) {
logElement.innerHTML += ('<p>' + msg + '</p>');
}
function capture() {
log('capture: ' + this.firstChild.nodeValue.trim());
}
function bubble() {
log('bubble: ' + this.firstChild.nodeValue.trim());
}
function clearOutput() {
logElement.innerHTML = "";
}
var divs = document.getElementsByTagName('div');
for (var i = 0; i < divs.length; i++) {
divs[i].addEventListener('click', capture, true);
divs[i].addEventListener('click', bubble, false);
}
var clearButton = document.getElementById('clear');
clearButton.addEventListener('click', clearOutput);
p {
line-height: 0;
}
div {
display:inline-block;
padding: 5px;
background: #fff;
border: 1px solid #aaa;
cursor: pointer;
}
div:hover {
border: 1px solid #faa;
background: #fdd;
}
<div>1
<div>2
<div>3
<div>4
<div>5</div>
</div>
</div>
</div>
</div>
<button id="clear">clear output</button>
<section id="log"></section>
関連
-
Vueの要素ツリーコントロールに破線を追加する説明
-
[解決済み】ローカルファイルを開くことができません - Chrome: ローカルリソースの読み込みが許可されていない
-
[解決済み] 配列から特定の項目を削除するにはどうすればよいですか?
-
[解決済み] JavaScriptで "use strict "は何をするのか、その根拠は?
-
[解決済み] let "と "var "の使い分けは?
-
[解決済み] JavaScriptでオブジェクトをディープクローンする最も効率的な方法は何ですか?
-
[解決済み] GUID / UUIDの作成方法
-
[解決済み] callとapplyの違いは何ですか?
-
[解決済み] event.preventDefault() vs. return false
-
[解決済み] Bowerとnpmの違いは何ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
要素ツリー制御によるvueTreeテーブル
-
vue3.0プロジェクトのアーキテクチャを構築するための便利なツール
-
vueの補間表現とv-textディレクティブの違いについて
-
vueのプロジェクトでモックを使用する方法を知っていますか?
-
Vueの「データを聴く」原則を解説
-
[解決済み】React - uncaught TypeError: 未定義のプロパティ 'setState' を読み取れない
-
[解決済み】"フォームが接続されていないため、フォームの送信がキャンセルされました "というエラーの取得について
-
[解決済み】JavaScriptエラー(Uncaught SyntaxError: Unexpected end of input)
-
[解決済み】(Google Map API) Geocodeは以下の理由で成功しませんでした。REQUEST_DENIED
-
フロントエンド非同期(アシンク)ソリューション(全ソリューション)