ホームページ >ウェブフロントエンド >jsチュートリアル >JavaScriptのイベントストリームとイベントハンドラとは何かを詳しく解説

JavaScriptのイベントストリームとイベントハンドラとは何かを詳しく解説

伊谢尔伦
伊谢尔伦オリジナル
2017-07-24 15:42:502040ブラウズ

JS と HTML 間の対話はイベントを通じて実現されます。イベントは、ドキュメントまたはブラウザ ウィンドウ内で発生する対話の特定の瞬間です。リスナー (またはハンドラー) を使用してイベントをスケジュールし、イベントの発生時に適切なコードが実行されるようにすることができます。従来のソフトウェア エンジニアリングではオブザーバー パターンとして知られており、これはページの動作とページの外観の間の疎結合をサポートします。

イベントフロー

イベントフローは、ページからイベントを受け取る順序を記述します。

イベントバブリング

イベントは、最初に最も具体的な要素 (ドキュメント内で最も深いネストレベルを持つノード) によって受信され、その後、より具体的ではないノード (ドキュメント) に上方に伝播します。以下の HTML ページを例に挙げると、ページ上のボタンをクリックすると、37a9605a910bf1fbe848fe3f47ab78d9、1d6e7d87652dd104f173dbf7284e2799、< の順にイベントが伝播されます。つまり、イベントのバブリングとは、イベントをトリガーした基礎となる要素からドキュメント オブジェクトまで、イベントが DOM ツリーに沿って上向きに伝播することを意味します。


<html>
 <head>
  <title>Test</title>
 </head>
 <body>
  <button id="myBtn">A Btn</button>
 </body>
</html>

イベントキャプチャ

イベントバブリングの考え方とは反対に、イベントキャプチャの考え方は、より具体的でないノードがより早くイベントを受信し、最も具体的なノードが最後にイベントを受信する必要があるということです。 。上記の例では、ページ上のボタンをクリックした後、ドキュメント、、、 の順に「クリック」イベントが伝播されます。つまり、イベントのキャプチャとは、イベントがドキュメント オブジェクトからイベントの実際のターゲット要素まで DOM ツリーに沿って下方向に伝播することを意味します。

DOMイベントの流れ

「DOMレベル2イベント」で指定されるイベントには、イベントキャプチャステージ、ターゲットステージ、イベントバブリングステージの3つのステージがあります。最初に行われるのはイベント キャプチャであり、イベントを傍受する機会が提供されます。その後、実際のターゲットがイベントを受信します。最後のフェーズはバブリングフェーズで、イベントに応答できます。

引き続き前のボタンのクリックを例に挙げますが、DOM イベント フローでは、キャプチャ フェーズ中に、「クリック」イベントがドキュメントから開始され、body 要素に渡されます (実際のターゲット ボタンは受信しないことに注意してください)キャプチャフェーズ中のイベント)。ターゲットフェーズでは、ボタン要素が「クリック」イベントを受け取ります。最後に、バブリングフェーズでは、イベントがドキュメントに伝播されます。

イベントハンドラー

イベントとは、ユーザーまたはブラウザ自体によって実行される特定のアクションであり、イベントに応答する関数はイベントハンドラーまたはイベントリスナーと呼ばれます。

HTMLイベントハンドラー

ここでのHTMLイベントハンドラーは、属性(属性)を介してHTML要素に直接定義されたイベントハンドラーを指します。以下のコード例を参照してください。この場合、イベント ハンドラーは要素の属性値をカプセル化する関数を作成します。この値はイベントのターゲット要素と等しくなります。この方法でイベント ハンドラーを指定することにはいくつかの欠点があるため、お勧めできません。


<button onclick="alert(&#39;HaHa~&#39;)">Btn-1</button>
<button onclick="alert(&#39;event.type&#39;)">Btn-2</button>
<button onclick="handler()">Btn-3</button>
<script type="text/javascript">
 function handler() {
  alert("Haha~");
 }
</script>

DOM レベル 0 イベント ハンドラー

JS を通じてイベント ハンドラーを指定する従来の方法は、イベント ハンドラー プロパティに関数を割り当てることです。以下のコード例を参照してください。このように指定されたイベント ハンドラーは、現在の要素を参照する要素のスコープ内で実行されます。この方法で追加されたイベント ハンドラーは、イベント フローのバブリング フェーズ中に処理されます。イベントを削除したい場合は、onclick の値を空に設定するだけです。


var btn = document.getElementById("myBtn");
btn.onclick = function() {
 console.log("this.id"); // "myBtn"
};
// 删除事件处理程序
btn.onclick = null;

DOM2レベルイベントハンドラ

「DOM2レベルイベント」は、イベントハンドラを指定および削除するための2つのメソッド、addEventListener()とremoveEventListener()を定義します。これら 2 つのメソッドはすべての DOM ノードに含まれています。どちらのメソッドも、処理対象のイベント、処理関数、およびブール値の 3 つのパラメーターを受け取ります。最後のブール値は、true の場合はイベント ハンドラーがキャプチャ フェーズ中に呼び出されることを意味し、false の場合はイベント ハンドラーがバブリング フェーズ中に呼び出されることを意味します。 DOM0 レベルのメソッドと同様に、ここで追加されたイベント ハンドラーも、それがアタッチされている要素のスコープ内で実行されます。 DOM2 レベルのメソッドを使用してイベント ハンドラーを追加する利点は、複数のイベント ハンドラーを追加できることです。これらのイベント ハンドラーは、追加された順序で起動されます。以下はコード例です。


var btn = document.getElementById("myBtn");
// 添加,触发点击事件时先输出"myBtn"再输出"HaHa~"
btn.addEventListener("click", function() {
 console.log(this.id);
}, false);
btn.addEventListener("click", function() {
 console.log("HaHa~");
}, false);

addEventListener() を通じて追加されたイベントは、removeEventListener() を通じてのみ削除できます。削除時に渡されるパラメータは、追加時に使用されるパラメータと一致している必要があります。また、addEventListener()で追加した匿名関数は削除できないことも意味します。追加時に渡した匿名関数をremoveEventListener()に渡すことができないため、削除時に同じ関数を記述しても、この関数は単なるNew匿名関数になります。以下のコード例をご覧ください:


var btn = document.getElementById("myBtn");
// 无法删除匿名函数
btn.addEventListener("click", function() {
 console.log(this.id);
}, false);
btn.removeEventListener("click", function() {
 console.log(this.id);
}, false);

// 正确的添加和删除方式
function handler() {
 console.log(this.id);
}
btn.addEventListener("click", handler, false);
btn.removeEventListener("click", handler, false);

大多数情况下,都是将事件处理程序添加到事件流的冒泡阶段,这样可以最大限度地兼容各种浏览器。最好只在需要在事件到达目标之前截获它的时候才将事件处理程序添加到捕获阶段。JS高级程序设计上给出的建议是,如果不是特别需要,不建议在事件捕获阶段注册事件处理程序。

IE事件处理程序

IE实现了与DOM中类似的两个方法: attachEvent()和deleteEvent()。这两个方法接收两个参数,事件处理程序名称和事件处理程序。注意,第一个参数是事件处理程序名称而不是事件名称,也就是说在注册点击事件的处理程序时应该传入”onclick”而不是”click”,这里跟DOM的方法有些差别。另外,这两个方法注册的事件处理程序是在全局作用域中运行而不是元素作用域,this的值指向window。还有一点需要特别小心,通过attachEvent()方法也可以添加多个事件处理程序,但是它们的执行顺序却不是按照它们被添加的顺序,而是完全相反,跟DOM方法截然不同。突然觉得IE真的特别反人类~~~下面是代码示例:


var btn = document.getElementById("myBtn");
function handler1() { // ... }
function handler2() { // ... }
// 添加,触发点击事件时先执行handler2再执行handler1
btn.attachEvent("onclick", handler1);
btn.attachEvent("onclick", handler2);
// 删除
btn.deleteEvent("onclick", handler1);
btn.deleteEvent("onclick", handler2);

以上がJavaScriptのイベントストリームとイベントハンドラとは何かを詳しく解説の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。