ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScript DOM イベントに関する 2 つのこと model_javascript のヒント

JavaScript DOM イベントに関する 2 つのこと model_javascript のヒント

WBOY
WBOYオリジナル
2016-05-16 18:22:41923ブラウズ
イベント キャプチャの実装上の問題

W3C DOM Level2 イベント モデル仕様では、DOM ツリー内のイベントの伝播プロセス (ルート ノードからターゲット ノードまで) が 2 つに分かれています。ステージ: キャプチャーとバブリング。次の図は、プロセス全体を大まかに示しています。
JavaScript DOM イベントに関する 2 つのこと model_javascript のヒント
(W3C より)

キャプチャ イベントを作成する場合は、W3C イベント モデルをサポートするブラウザで、 addEventListener の 3 番目の要素 3 つのパラメーターを true に設定するだけです。例:
コードをコピー コードは次のとおりです。

document.getElementById('foo) ').addEventListener ('click',function(){alert('Hello, world!');},true);

少し前にイベントキャプチャを理解したかったので理解しました。イベント キャプチャは、Firefox 2、Windows 上の Safari 3、および Opera 9 で実行されました (もちろん、IE はイベント キャプチャをサポートしていないため...)。実験の原理を次の図に示します。 🎜>
JavaScript DOM イベントに関する 2 つのこと model_javascript のヒントID は div1 で、div2 の両方の要素はキャプチャフェーズでイベントハンドラー関数にバインドされているため、次のようになります:

#div1 (青い領域) がクリックされると、アラートが表示されます。 "div1"
#div2 をクリックすると (黄色の領域)、最初に "div1" がアラートされ、次に "div2" がアラートされる必要があります。これは、イベントのキャプチャ段階でイベントがルート要素から下方向に伝播されるためです。 #div1 は #div2 の親要素であり、自然にバインドされています。#div1 のクリック イベントも、#div2 のクリック イベントの前に実行されます。
ただし、上記のアイデアは Windows の Firefox 2 と Safari 3 でのみ機能します。Opera 9 では、次のようになります。

#div1 (青い領域) をクリックしても、何も起こりません。
#div2 (黄色の領域) をクリックすると、「div1」がアラートされ、その後は何も起こりません
Opera 9 では、対象要素 (TargetElement) のクリック イベントが実行されないことがわかります。 Realazy の指導により (orz...)、「イベント キャプチャの説明」という記事を見つけ、Opera での実装が正しいことがわかりました。この記事には次のような文章があります:

DOM 仕様では、イベントのキャプチャはターゲットに到達する前にイベントを検出することが目的であるため、ターゲットで起動すべきではないと述べています。 Gecko と Safari のバグのため、主に Firefox またはその他の Gecko ベースのブラウザでテストされている Web コンテンツは、キャプチャ リスナーがターゲットで起動することを期待していることがありますが、Opera 7、8、および現在のリリース 9 では、その実装が正しいため失敗します。
一般的な考え方は次のとおりです: DOM 仕様では、イベントのキャプチャの目的はターゲット要素に到達する前にイベントを監視することであるため、イベントのキャプチャはターゲット要素で実行すべきではないと述べています。 Firefox と Safari の実装にはバグがあります。

W3C の DOM イベント仕様の元の言葉を見てみましょう:

キャプチャする EventListener は、登録されている EventTarget に直接ディスパッチされるイベントによってはトリガーされません。
したがって、In。イベント伝播全体の実行順序は次のとおりです:

親要素 (存在する場合) のすべてのキャプチャ イベントは上から下に実行されます
ターゲット要素のバブリング イベント (存在する場合)
親要素内のすべてのバブリング イベント (存在する場合) は下から上に実行されます
これを理解した後は、少なくともまだはイベント キャプチャを使用しない方が良いかもしれません。

IE の高度なイベント処理モデルの問題
バインディングの重複
IE には addEventListener はありませんが、独自のattachEvent、いわゆる Microsoft モデルもあります。この 2 つの実装は基本的に同じですが、attachEvent の最初のパラメータ (イベント タイプ) には「on」を追加する必要がありますが、addEventListener では追加する必要がありません。また、attachEvent はイベント キャプチャをサポートしていないため、3 番目のパラメータはありません。

しかし、attachEvent にはバインディング イベントが繰り返されるという重大な問題があります。 (これは JavaScript の ppk から学びます)

例:

コードをコピー コードは次のとおりです。
function SayHello(){
alert('Hello, world!')
}
// W3C モデル
$('div1').addEventListener( ' click'、sayHello、false);
$('div1').addEventListener('click'、sayHello、false);
// Microsoft モデル
$('div1').attachEvent(' onclick '、sayHello);
$('div1').attachEvent('onclick'、sayHello);
W3C モデルでは、同じイベント ハンドラー関数のバインディングは無視されます。つまり、2 番目の $('div1').addEventListener('click',sayHello,false); は無視されます。

Microsoft モデルでは、2 番目の $('div1').attachEvent('onclick',sayHello); も実行されるため、#div1 をクリックすると、アラート ボックスが 2 回表示されます。さらに、detachEvent 中に、#div1 のクリック イベントからsayHello を完全に削除するには 2 つの detachEvent も必要です。

alertID() を引き続き使用しないのはなぜですか?
これは、IE のイベント モデルの別の欠陥によるものです。このように、W3C モデルでは、alertID で this キーワードがバインドされている要素を参照します。 #div1 または #div2 を置き換えます。

しかし、Microsoft モデルでは、this がサポートされていないと、this.id は未定義になります。これは、現時点で this が wi​​ndow オブジェクトを参照しているためです。
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。