ホームページ > ウェブフロントエンド > jsチュートリアル > JavaScript イベント学習 第 8 章 イベントのシーケンス_JavaScript スキル

JavaScript イベント学習 第 8 章 イベントのシーケンス_JavaScript スキル

WBOY
リリース: 2016-05-16 18:35:00
オリジナル
1002 人が閲覧しました

基本的な質問は簡単です。 1 つの要素が別の要素内に含まれているとします。

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

-------- --- -----------------------
|
| ---- -------- |要素 2 | - |

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


これら 2 つの要素にはすべて onclick イベント ハンドラーがあります。ユーザーが要素 2 をクリックすると、要素 2 と要素 1 の両方でクリック イベントがトリガーされます。しかし、最初に起こったのはどの出来事でしょうか?どのイベント ハンドラーが最初に実行されますか?言い換えれば、イベントの順序は何ですか?

2 つのモード
Netscape と Microsoft の両方が、過去の悪い時代に独自の決定を下したことは疑いの余地がありません。
Netscape は、element1 が最初に発生したと述べました。これをイベントキャプチャと呼びます。
Microsoft は要素 2 が最初に発生したと考えています。これをイベントバブリングと呼びます。
これら 2 つのイベントの順序はまったく逆です。 IE はイベント バブリングのみをサポートします。 Mozilla、Opera 7、Konqueror は両方をサポートしています。以前の Opear ブラウザと iCab ブラウザはどちらもサポートしていません。

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


コードをコピーします コードは次のとおりです。
------| |------------------
| |
| |------| ------ ------------------ |
| イベントのキャプチャ | ------ ----------------


要素 1 のイベント ハンドラーが最初に実行され、次に要素 2 が実行されます。

イベントバブリング
ただし、イベントバブリングを使用する場合は




コードをコピーします
コードは次のとおりです。 / --------------- | ------------------ | -- ------------
| イベントバブリング | --- ------------------


要素 2 のイベント ハンドラが最初に実行され、要素 1 のイベント ハンドラが後で実行されます。 。

W3C モード
W3C はこの戦争で重力を維持することを決定しました。 W3C イベント モデルでは、発生したイベントはターゲット要素に到達するまでまずキャプチャされ、その後バブルアップされます。



コードをコピーします


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

--- | --- -----------| |------ | -- ----| |--| | ---- ------------------------ | W3C イベントモデル | ---- -----------------------------
デザイナーは、イベント ハンドラーをキャプチャ ステージまたはバブリング ステージに登録することを選択できます。これは、以前のアドバンスト モードで導入された addEventListener() メソッドを通じて実現できます。最後のパラメータが true の場合はイベント キャプチャに設定され、false の場合はイベント バブリングに設定されます。

次のように書くとします。
element1.addEventListener('click',doSomething2,true)
element2.addEventListener('click',doSomething,false)
ユーザーが element2 をクリックした場合次のことが起こります:
、キャプチャフェーズでクリックイベントが発生します。 element2の親要素にonclickイベントハンドラがあればそれが実行されるようです。
、イベントは element1 で doSomething2() を見つけ、実行されます。
では、イベントはターゲット自体に渡され、他のキャプチャ フェーズ プログラムはありません。イベントはバブリングフェーズに入り、doSomething() が実行されます。これは、バブリングフェーズで element2 によって登録されたイベント ハンドラーです。
の場合、イベントは上方に渡され、バブリング段階で親要素がイベント ハンドラーを設定しているかどうかがチェックされます。ここには誰もいないので、何も起こりません。
逆:
element1.addEventListener('click',doSomething2,false)
element2.addEventListener('click',doSomething,false)

ユーザーが element2 をクリックした場合発生:
、キャプチャフェーズでイベントクリックが発生します。このイベントは、キャプチャ フェーズ中に element2 の親要素にイベント ハンドラーが登録されているかどうかを確認しますが、ここでは当てはまりません。
、イベントはターゲット自体に渡されます。次に、バブリングフェーズが開始され、dosomething() が実行されます。これは、element2 のバブリングフェーズに登録されたイベント ハンドラーです。
では、イベントは上向きに渡され続け、バブリング段階で親要素がイベント ハンドラーを登録したかどうかを確認します。
、イベントが element1 を見つけた後、doSomething2() が実行されました。

レガシー モードでの互換性
W3C DOM をサポートするブラウザの場合、レガシー イベント登録

element1.onclick = doSomething2;
はバブリング ステージで登録されたとみなされます。

イベント バブリングの使用
イベントのキャプチャやバブリングを認識しているデザイナーはほとんどいません。今日の Web ページ作成の世界では、バブリング イベントを一連のイベント ハンドラーで処理する必要はないようです。また、クリック後に発生する一連のイベントによってユーザーが混乱する可能性があるため、通常はイベント ハンドラー コードをある程度独立させておく必要があります。ユーザーが 1 つの要素をクリックすると何かが起こり、別の要素をクリックすると別のことが起こります。
もちろん、これは将来変更される可能性があります。モデルの前方互換性を維持することが最善です。しかし、現在最も実用的なイベント キャプチャとバブリングは、デフォルト関数の登録です。

それは常に発生します
最初に理解する必要があるのは、イベントのキャプチャまたはバブリングは常に発生するということです。ページ全体に onclick イベントを定義する場合:
コードをコピーします コードは次のとおりです:

document.onclick = doSomething;
if (document.captureEvents) document.captureEvents(Event.CLICK);

任意の要素のクリック時間がページに表示されます。このイベント ハンドラーを開始します。先行するイベント ハンドラーが明示的にバブリングを防止する場合にのみ、バブリングはページ全体に渡されません。


を使用 ドキュメント全体で各イベントが停止するため、デフォルトのイベントハンドラーが可能になります。次のようなページがあるとします。
コードをコピーします コードは次のとおりです:

---- --------------------------------
| ドキュメント
| ---- ------- ------------ |
| ---- ------------

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

element1.onclick = doSomething;
element2.onclick = doSomething;


ユーザーが element1 または element2 をクリックすると、doSomething() が実行されます。必要に応じて、ここで彼の拡散を止めることもできます。そうでない場合は、defaultFunction() が実行されます。ユーザーが他の場所をクリックした場合も、defaultFunction() が実行されます。場合によってはこれが役立つこともあります。
ドラッグコードを記述する際には、グローバルイベントハンドラーの設定が必要です。通常、レイヤー上の Mousedow イベントはこのレイヤーを選択し、mousemove イベントに応答します。通常、マウスダウンはブラウザのバグを避けるためにこのレベルで登録されますが、他のイベント ハンドラーはドキュメント全体である必要があります。
ブラウザ ロジックの第一法則を思い出してください。ほとんど準備ができていないときに、何でも起こります。発生する可能性があるのは、ユーザーのマウスが激しく動き、コードが追いつかず、マウスがこのレイヤーに存在しなくなることです。
onmousemove イベント ハンドラーがレイヤーに登録されている場合、レイヤーがマウスの動きに応答しなくなると、ユーザーは間違いなく混乱します。
onmouseup イベント ハンドラーが特定のページに登録されている場合、ユーザーがマウスを放したときにプログラムはレイヤーをキャプチャせず、レイヤーはマウスとともに移動したままになります。
グローバル イベント ハンドラーの実行が保証されているため、この場合はイベント バブリングが重要です。

オフにしてください
ただし、通常は、関連するキャプチャとバブリングをすべてオフにする必要があります。さらに、ドキュメント構造が非常に複雑である場合 (多数の複雑なテーブルなど)、システム リソースを節約するためにバブリングをオフにする必要もあります。それ以外の場合、ブラウザーは親要素を 1 つずつチェックして、イベント ハンドラーがあるかどうかを確認する必要があります。存在しないかもしれませんが、探すのはやはり時間の無駄です。
Microsoft モードでは、イベントの cancelBubble プロパティを true に設定する必要があります。
window.event.cancelBubble = true
W3C モードでは、stopPropagation() メソッドを呼び出す必要があります。

e.stopPropagation()
これにより、このイベントのバブリングフェーズが停止します。イベントの攻略極限を防ぐことは基本的に不可能です。理由も知りたいです。
完全なクロスブラウザ コードは次のとおりです:
コードをコピーします コードは次のとおりです:

function doSomething(e)
{
if (!e) var e = window.event;
e.cancelBubble = true; ();
}

cancelBubble をサポートしていないブラウザで設定しても問題ありません。ブラウザはそのような属性を作成します。もちろん、安全のためだけでは意味がありません。

currentTarget
前に述べたように、イベントにはターゲットが含まれるか、srcElement にはイベントが発生した要素への参照が含まれます。この場合、ユーザーがクリックしたため、それは element2 です。
このターゲットはキャプチャ中およびバブリング中は変化しないことを理解することが重要です。
ただし、次のイベント ハンドラーを登録するとします。

element1.onclick = doSomething; 🎜>element2.onclick = doSomething;
ユーザーが element2 をクリックすると、doSomething() が 2 回実行されます。では、どの HTML 要素がこのイベントを処理するのかをどのようにして知ることができるのでしょうか? target/scrElement は答えを与えることができません。イベントの最初から element2 を指しています。
この問題を解決するために、W3C は currentTarget 属性を追加しました。これには、処理されるイベントの HTML 要素への参照が含まれています。これは、必要なものです。残念ながら、Microsoft モードには同様のプロパティがありません。
このキーワードも使用できます。この例では、currentTarget で始まる、処理中のイベントの HTML 要素を指します。

Microsoft モデルの問題
しかし、Microsoft のイベント登録モデルを使用する場合、this キーワードは HTML 要素にのみ適用されるわけではありません。その場合、 currentTarget のようなプロパティはありません。つまり、次のようにすると、

element1.attachEvent('onclick',doSomething)
element2.attachEvent('onclick',doSomething)
は実行されません。どの HTML 要素がイベントを処理しているかを知ることができます。これは Microsoft のイベント登録モデルの最も深刻な問題であるため、たとえ IE/win でのみ動作するプログラムであっても、このモデルは絶対に使用しないでください。
Microsoft が currentTarget のようなプロパティをすぐに追加することを願っていますか、それとも標準に従っていますか?私たちは早急にデザインを必要としています。

続き
学習を続けたい場合は、次の章をお読みください。
元のアドレス: http://www.quirksmode.org/js/events_order.html
私のツイッター: @rehawk
関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート