検索
ホームページウェブフロントエンドjsチュートリアルJavaScript イベントのバブリングとキャプチャとブロックの方法の詳細な説明_JavaScript スキル

1. 一連のイベント

この問題の原因は非常に単純です。別の要素内にネストされた要素があるとします。

コードをコピー コードは次のとおりです:

---------------------------------
| 要素 1 | ------- |

--------------------- ---- -------

: どちらも onClick イベント ハンドラーを持っています。ユーザーが要素 2 をクリックすると、要素 1 と要素 2 の両方のクリック イベントがトリガーされます。しかし、どのイベントが最初にトリガーされるのでしょうか?どのイベント ハンドラー関数が最初に実行されますか?言い換えれば、一連の出来事の正確な順序は何だったのでしょうか?

2. 2 つのモデル

予想通り、Netscape と Microsoft は、「ブラウザ戦争」の時代に対処するために 2 つの非常に異なるアプローチをとっていました。

Netscape は、要素 1 のイベントが最初に発生することを推奨しています。

Microsoft は、このイベントの順序がバブリング タイプと呼ばれていると主張しています。そのうちの出来事の順序は正反対です。 Explorer ブラウザはバブリング イベントのみをサポートしますが、Mozilla、Opera7、Konqueror は両方をサポートします。古い Opera と iCab はどちらもサポートしていません


3. イベントをキャプチャします

イベントのキャプチャを使用する場合


コードをコピーします

コードは次のとおりです: ---------------| |-----------------
| | --- --------| |---------- |
| |要素 2 / |
| -- ---------- |
| イベントのキャプチャ |
-------------------------- -- ------

: 要素 1 のイベント ハンドラーが最初にトリガーされ、要素 2 のイベント ハンドラーが最後にトリガーされます


4. バブルイベント

バブリングイベントを使用する場合

コードをコピーします

コードは次のとおりです: ---------------| |-----------------| | - ----------| |---------- |
| |
| ----------- |
| イベントバブリング |
-------------------------- -- -------

: 要素 2 の処理関数が最初にトリガーされ、続いて要素 1
がトリガーされます。

5. W3C モデル

W3c は、この戦いで正しい解決策を賢明に選択しました。 w3c イベント モデルで発生するイベントは、まずターゲット要素に到達するまでキャプチャ フェーズに入り、その後バブリング フェーズに入ります

コピー コード


コードは次のとおりです:

--
| | |
| -|
| |
|
| W3C イベント モデル |
-------------------------------------- ------
Web 開発者は、イベント処理関数をキャプチャ フェーズでバインドするかバブリング フェーズでバインドするかを選択できます。これは、最後のパラメータの addEventListener() メソッドによって実現されます。この関数の値が true の場合、キャプチャ フェーズでフェーズ バインド関数が返されます。それ以外の場合は、バブリング フェーズで関数がバインドされます。


コードをコピー とします。コードは次のとおりです。
element1 .addEventListener(' click',doSomething2,true)
element2.addEventListener('click',doSomething,false)

ユーザーが要素 2 をクリックすると、次に何が起こります:

(このイベントはここでの観光客のようなもので、外側から内側へ移動し、トリガーされた主要な要素に徐々に近づき、その後反対方向に去っていきます)

1. クリック イベントは最初にキャプチャ フェーズに入ります (要素 2 の方向に徐々に近づきます)。キャプチャフェーズで要素 2 の祖先要素のいずれかに onclick ハンドラーがあるかどうかを確認します

2. 要素 1 に onclick ハンドラーがあることが判明したため、doSomething2 が実行されます
3. イベントはターゲット自体をチェックします (要素 2) ) ですが、キャプチャフェーズには onclick ハンドラーがありません。さらに処理関数が見つかりました。イベントはバブリング段階に入り始め、要素 2 のバブリング段階にバインドされている関数である doSomething() が自然に実行されます。
4. イベントは要素 2 から離れて、バブリングフェーズ中に祖先要素にハンドラーがバインドされているかどうかを確認します。そのようなケースは存在しないため、何も起こりません
逆のケースは次のとおりです。

コードをコピーしますコードは次のとおりです。
element1.addEventListener('click',doSomething2,false)
element2.addEventListener('click',doSomething,false)

ユーザーが要素 2 をクリックすると、次のことが起こります:
1. イベントをクリックしてキャプチャフェーズに入ります。キャプチャフェーズで要素 2 の祖先要素のいずれかに onclick ハンドラーがあるかどうかを確認しますが、何も見つかりません

2. イベントはターゲット自体を検出します。イベントはバブリングフェーズに入り始め、要素 2 のバブリングフェーズにバインドされた関数が実行されます。 doSomething()
3. イベントがターゲットから離れ始めます。バブリング段階で要素 2 の祖先要素にハンドラー関数がバインドされているかどうかを確認します。要素 1 の
が実行されます。

6. 互換性と従来モード

w3c dom (Document Object Model) をサポートするブラウザーでは、従来のイベント バインディング メソッドは次のとおりです。


コードをコピー コードは次のとおりです。次のように: element1.onclick = doSomething2;
は、デフォルトでバブリング ステージにバインドされているとみなされます

7. バブリングイベントを使用する

バブリング イベントやイベントのキャプチャを意識的に使用する開発者はほとんどいません。彼らが現在作成している Web ページでは、イベントはバブルアップするため、複数の関数によって処理される必要はありません。しかし、マウスを 1 回クリックしただけでさまざまなことが起こる (バブリングにより複数の機能が実行される) ため、ユーザーが混乱することがあります。ほとんどの場合、処理関数は互いに独立している必要があります。ユーザーが要素をクリックしたときに何が起こるか、そしてユーザーが別の要素をクリックしたときに何が起こるかは、互いに独立しており、バブリングによってリンクされることはありません。

8. それはいつも起こります

最初に理解する必要があるのは、イベントのキャプチャまたはバブリングが常に発生しているということです。ページドキュメント全体に対して一般的な onclick 処理関数を定義する場合


コードをコピーします コードは次のとおりです:
document.onclick = doSomething;
if (document.captureEvents) document.captureEvents(Event.CLICK);

ページ上の任意の要素をクリックするクリック イベントは、最終的にページの最上位のドキュメント レイヤーまでバブルアップし、前の処理関数がバブリングが終了しないことを明示的に指定しない限り、一般的な処理関数をトリガーします。ドキュメントレベル全体に伝播されます


上記のコードの 2 番目の文に追加:

>>> まず IE について話しましょう
object.setCapture() オブジェクトが setCapture されると、そのメソッドはキャプチャのためにドキュメント全体に継承されます。
ドキュメント全体をキャプチャするためにメソッドを継承する必要がない場合は、object.releaseCapture() を使用します
>>>その他
Mozilla にも同様の機能がありますが、メソッドは少し異なります
window.captureEvents (Event.eventType)
window.releaseEvents(Event.eventType)
>>>例

コードをコピー コードは次のとおりです:
//次の文だけがある場合、obj がクリックされたときのみクリックがトリガーされます obj.onclick = function(){alert(" something")}
//次の文を追加すると、メソッドはドキュメント (またはウィンドウ、ブラウザによって異なります) に継承され、
obj.captureEvents(Event.click); //FF
obj.setCapture() // IE

9. 使用方法

イベントの伝播はページドキュメント (このトップレベル) で終了するため、次のようなページがあると仮定すると、デフォルトのイベントハンドラーが可能になります。

コードをコピー コードは次のとおりです:

-------------------------- ---- --------
| 要素 1 |
| ----- |

----- --------------------------------- -
element1.onclick = doSomething;
element2.onclick = doSomething;
document.onclick =defaultFunction;


ユーザーが要素 1 または要素 2 をクリックすると、doSomething() が実行されます。イベントがdefaultFunction()にバブルアップしたくない場合は、必要に応じて、ここでイベントがバブルアップするのを防ぐことができます。ただし、ユーザーがページ上の別の場所をクリックした場合でも、defaultFunction() は実行されます。この効果は場合によっては役に立つかもしれません。

設定ページ - 処理機能でより大きなトリガー領域を設定できるようにします。これは「ドラッグ エフェクト」スクリプトで必要です。一般に、要素レイヤーでの Mousedown イベントの発生は、その要素が選択され、mousemove イベントに応答できるようになることを意味します。通常、マウスダウンはブラウザのバグを避けるためにこの要素レイヤーにバインドされますが、他の 2 つのイベント関数のスコープはページ全体 (?) でなければなりません

ブラウザ学の第一法則を思い出してください。何が起こってもおかしくありません。それが少なくともある程度の準備ができているときです。そこで何が起こるかというと、ユーザーがドラッグ&ドラッグするときにページ上でマウスを大きく動かしますが、スクリプトがその大きな振幅に応答できず、マウスが要素レイヤーに留まらなくなるということです

1. onmouseover ハンドラー関数が要素レイヤーにバインドされている場合、この要素レイヤーはマウスの動きに反応しなくなるため、ユーザーは違和感を感じます。

2. onmouseup ハンドラー関数が要素レイヤーにバインドされている場合の場合、イベントはトリガーされません。その結果、ユーザーがこの要素レイヤーをドロップしようとしても、要素レイヤーはマウスの動きに応答し続けます。これはさらなる混乱を引き起こすでしょう (?)


この例では、ハンドラー関数をページ レベルに配置することで常に確実に実行できるため、イベント バブリングは非常に便利です。

10. オフにします (イベントのバブルを防ぐため)

ただし、一般的には、各機能が相互に干渉しないように、すべてのバブリングとキャプチャをオフにする必要があります。さらに、ドキュメント構造が非常に複雑である場合 (多数のテーブルが相互にネストされているなど)、システム リソースを節約するためにバブリングをオフにすることもできます。この時点で、ブラウザはターゲット要素のすべての祖先をチェックして、ハンドラー関数があるかどうかを確認する必要があります。たとえ誰も見つからなかったとしても、先ほどの捜索にはまだ時間がかかります

Microsoft モデルでは、イベントの cancelBubble プロパティを true に設定する必要があります


コードをコピーします コードは次のとおりです以下:window.event.cancelBubble = true

w3c モデルでは、イベントの stopPropagation() メソッドを呼び出す必要があります
コードをコピーします コードは次のとおりです:
e.stopPropagation()

これにより、すべてのバブリングが外側に伝播するのを防ぎます。クロスブラウザーの解決策として、これを実行する必要があります:
コードをコピーします コードは次のとおりです:

関数 doSomething(e)

{
if (!e) var e = window.event;

e.cancelBubble = true;

if (e.stopPropagation) e.stopPropagation();

}

cancelBubble 属性をサポートするブラウザで cancelBubble を設定しても問題はありません。ブラウザは肩をすくめてこの属性を作成します。もちろん、これで実際にバブリングがキャンセルされるわけではありませんが、少なくともこのコマンドが安全で正しいものであることが保証されます

11. 現在のターゲット

前に見たように、イベントは target または srcElement 属性を使用して、イベントが発生したターゲット要素 (つまり、ユーザーが最初にクリックした要素) を示します。この場合、クリックしたのは要素 2 です。

キャプチャまたはバブリングフェーズ中のターゲット要素は変化せず、常に要素 2 に関連付けられていることを理解することが非常に重要です。

しかし、次の関数をバインドするとします。

コードをコピーします コードは次のとおりです:
element1。 onclick = doSomething;

element2.onclick = doSomething;


ユーザーが要素 2 をクリックすると、doSomething() が 2 回実行されます。しかし、どの HTML 要素がこのイベントに応答しているかをどうやって知るのでしょうか? target/srcElement も手がかりを与えませんが、イベントの原因である (ユーザーがクリックしたものであるため) 人々は常に要素 2 を好むでしょう。
この問題を解決するために、w3c は、イベントを処理している要素を指す currentTarget 属性を追加しました。これはまさに必要なものです。残念ながら、Microsoft モデルには同様の属性はありません
「this」キーワードを使用することもできます。上記の例では、currentTarget など、イベントを処理する HTML 要素に相当します。

12. Microsoft モデルの問題

しかし、Microsoft イベント バインディング モデルを使用する場合、this キーワードは HTML 要素と同等ではありません。 Lenovo には、currentTarget プロパティ (?) に似た Microsoft モデルがありません。上記のコードに従うと、次のことを意味します:

コードをコピー コードは次のとおりです:
element1.attachEvent('onclick',doSomething)

element2.attachEvent('onclick',doSomething)


どの HTML 要素がイベントの処理を担当しているのかを正確に知ることができません。これが Microsoft のイベント バインディング モデルの最も深刻な問題です。これは、Windows で IE 専用のアプリケーションを開発する場合でも、私が決して使用しない理由でもあります

currentTarget のようなプロパティをすぐに追加できるようにしたいと思っています。それとも標準に従うのでしょうか? Web 開発者にはこの情報が必要です

追記:

私は実際に JavaScript を使用したことがないため、この記事にはよく理解できない部分がいくつかあります。そのため、ドラッグ効果に関するセクションなど、追加または追加があれば、唐突に翻訳することしかできません。ご質問がありましたら、メッセージを残していただけますようお願いいたします。

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
es6数组怎么去掉重复并且重新排序es6数组怎么去掉重复并且重新排序May 05, 2022 pm 07:08 PM

去掉重复并排序的方法:1、使用“Array.from(new Set(arr))”或者“[…new Set(arr)]”语句,去掉数组中的重复元素,返回去重后的新数组;2、利用sort()对去重数组进行排序,语法“去重数组.sort()”。

JavaScript的Symbol类型、隐藏属性及全局注册表详解JavaScript的Symbol类型、隐藏属性及全局注册表详解Jun 02, 2022 am 11:50 AM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于Symbol类型、隐藏属性及全局注册表的相关问题,包括了Symbol类型的描述、Symbol不会隐式转字符串等问题,下面一起来看一下,希望对大家有帮助。

原来利用纯CSS也能实现文字轮播与图片轮播!原来利用纯CSS也能实现文字轮播与图片轮播!Jun 10, 2022 pm 01:00 PM

怎么制作文字轮播与图片轮播?大家第一想到的是不是利用js,其实利用纯CSS也能实现文字轮播与图片轮播,下面来看看实现方法,希望对大家有所帮助!

JavaScript对象的构造函数和new操作符(实例详解)JavaScript对象的构造函数和new操作符(实例详解)May 10, 2022 pm 06:16 PM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于对象的构造函数和new操作符,构造函数是所有对象的成员方法中,最早被调用的那个,下面一起来看一下吧,希望对大家有帮助。

JavaScript面向对象详细解析之属性描述符JavaScript面向对象详细解析之属性描述符May 27, 2022 pm 05:29 PM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于面向对象的相关问题,包括了属性描述符、数据描述符、存取描述符等等内容,下面一起来看一下,希望对大家有帮助。

javascript怎么移除元素点击事件javascript怎么移除元素点击事件Apr 11, 2022 pm 04:51 PM

方法:1、利用“点击元素对象.unbind("click");”方法,该方法可以移除被选元素的事件处理程序;2、利用“点击元素对象.off("click");”方法,该方法可以移除通过on()方法添加的事件处理程序。

foreach是es6里的吗foreach是es6里的吗May 05, 2022 pm 05:59 PM

foreach不是es6的方法。foreach是es3中一个遍历数组的方法,可以调用数组的每个元素,并将元素传给回调函数进行处理,语法“array.forEach(function(当前元素,索引,数组){...})”;该方法不处理空数组。

整理总结JavaScript常见的BOM操作整理总结JavaScript常见的BOM操作Jun 01, 2022 am 11:43 AM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于BOM操作的相关问题,包括了window对象的常见事件、JavaScript执行机制等等相关内容,下面一起来看一下,希望对大家有帮助。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

DVWA

DVWA

Damn Vulnerable Web App (DVWA) は、非常に脆弱な PHP/MySQL Web アプリケーションです。その主な目的は、セキュリティ専門家が法的環境でスキルとツールをテストするのに役立ち、Web 開発者が Web アプリケーションを保護するプロセスをより深く理解できるようにし、教師/生徒が教室環境で Web アプリケーションを教え/学習できるようにすることです。安全。 DVWA の目標は、シンプルでわかりやすいインターフェイスを通じて、さまざまな難易度で最も一般的な Web 脆弱性のいくつかを実践することです。このソフトウェアは、

PhpStorm Mac バージョン

PhpStorm Mac バージョン

最新(2018.2.1)のプロフェッショナル向けPHP統合開発ツール

AtomエディタMac版ダウンロード

AtomエディタMac版ダウンロード

最も人気のあるオープンソースエディター

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

このプロジェクトは osdn.net/projects/mingw に移行中です。引き続きそこでフォローしていただけます。 MinGW: GNU Compiler Collection (GCC) のネイティブ Windows ポートであり、ネイティブ Windows アプリケーションを構築するための自由に配布可能なインポート ライブラリとヘッダー ファイルであり、C99 機能をサポートする MSVC ランタイムの拡張機能が含まれています。すべての MinGW ソフトウェアは 64 ビット Windows プラットフォームで実行できます。