原文章:https://wangdoc.com/javascript/index.html
イベントモデル
モニター機能
リスニング機能(リスナー)によって、あるイベントモデルブラウザは、イベントに反応します。事件後、ブラウザはこのイベントをリッスンし、対応する機能の実施を監視します。これは、イベント駆動型のプログラミング・モデル(イベント駆動型)のプログラミングの主要な方法です。
JavaScriptを使用すると、イベントをリッスンする機能をバインドすることができる3つの方法があります。
オンのHTML属性
HTML言語は、要素の属性、コードが直接特定のイベントを監視定義されたことができます。
<body onload="doSomething()">
<div onclick="console.log('触发事件')">
上記コードbody
のノードload
イベント、div
ノードclick
イベント、指定されたリスナー・コード。イベントが発生すると、それがコードを実行します。
イベント・モニター・エレメントの属性はれるon
ような、イベント名と結合onload
されているon + load
表現load
イベントをリッスンするコード。
これらのプロパティの値はむしろ機能よりも、コードを実行することに留意されたいです。
<!-- 正确 -->
<body onload="doSomething()">
<!-- 错误 -->
<body onload="doSomething">
指定したイベントが発生すると、on-
プロパティの値は、それがJavaScriptエンジンの実装に渡されるよう。あなたが機能を実行したいのであれば、括弧のペアを追加することを忘れないでください。
唯一のバブリング段階でトリガするモニタコードを指定するには、このメソッドを使用します。
<div onClick="console.log(2)">
<button onClick="console.log(1)">点击</button>
</div>
上記のコードは、<button>
ある<div>
子要素。イベントがトリガされますイベントを。起因するモニタコードの性質だけなので、最初の結果をクリックして、バブリング段階でトリガーされるが出力され、その後、出力の子要素からのイベントが親要素にバブルを始めたこと。<button>
click
<div>
click
on-
1
2
直接on-
、要素ノードによって特性setAttribute
設定方法のon-
属性、効果は同じです。
el.setAttribute('onclick', 'doSomething()');
// 等同于
// <Element onclick="doSomething()">
イベントは、要素ノードの属性
イベント属性要素ノードオブジェクトは、リスナー関数を指定することができます。
window.onload = doSomething;
div.onclick = function (event) {
console.log('触发事件');
};
リスナー関数が唯一のバブリング段階でトリガーされる指定するには、このメソッドを使用します。
このアプローチHTML-のことに注意on-
差プロパティは、その値が関数名である(doSomething
)、後者とは異なり、コードは、完全な(聞く与えなければならないdoSomething()
)を。
EventTarget.addEventListener()
すべてのDOMノードインスタンスが有するaddEventListener
ノードのイベントリスナー関数を定義するために使用する方法を。
window.addEventListener('load', doSomething, false);
addEventListener
この方法の詳細については、参照のEventTarget
章を。
概要
三つの方法、一緒に、2件の書き込みをHTMLとは別のJavaScriptコードの原則に違反し最初の「オンのHTML属性」以上、労働の符号分割を助長されていませんので、お勧めできません。
あなたは2つの定義した場合、ある同じイベント、リスナー関数を定義することができる第二の欠点「イベント属性要素ノード」onclick
事前定義された時間範囲の後に、プロパティを。そのため、お勧めできません。
第三は、EventTarget.addEventListener
この方法が推奨されるリスナー関数を指定することです。それは次のような利点があります。
- 同じイベントリスナーは、複数の機能を追加することができます。
- どの段階で指定する機能(キャプチャ段階またはバブリング段階)トリガ・モニタ機能。
- DOMノードに加えて、他のオブジェクト(例えば
window
、XMLHttpRequest
等)も、JavaScript関数インタフェース統一全体を監視するに等しい。このインタフェースを有します。
この時点
内部モニタ機能this
要素ノードのトリガ・イベントを指します。
<button id="btn" onclick="console.log(this.id)">点击</button>
上記のコードの実装では、出力はをクリックしますbtn
。
デュレーションの機能上の2つの書かれた他、this
ポイントはtrueです。
// HTML 代码如下
// <button id="btn">点击</button>
var btn = document.getElementById('btn');
// 写法一
btn.onclick = function () {
console.log(this.id);
};
// 写法二
btn.addEventListener(
'click',
function (e) {
console.log(this.id);
},
false
);
ボタンをクリックすると、出力された後、両方のスペルは、バリアントbtn
。
イベントの伝播
イベントの後、子要素、および親要素間スプレッド(伝播)を発生します。この伝播は、3つの段階に分けています。
- 第一段階:
window
ターゲット・ノードへの導電性物体は、(上層が下層に達した)、「捕獲位相」(キャプチャ段階)と呼ばれます。 - 第二段階:ターゲット・ノード・トリガに、「目標位相」(目標位相)として知られています。
- 第三段階:ターゲット・ノードバック導電性から
window
(底層から返された)オブジェクトは、「バブル期」(バブリング相)と呼ばれます。
この3段階の伝播モデル、複数のノード上で同じイベントトリガを行います。
<div>
<p>点击</p>
</div>
上記のコードでは、<div>
ノード間有する<p>
ノード。
これら二つのノードに設定されている場合はclick
イベント(捕捉およびバブリング段階各ノード、モニタ機能最大各セット)の機能を監視する4つのモニター機能の合計を設定します。その後、<p>
クリックclick
イベントが4回をトリガします。
var phases = {
1: 'capture',
2: 'target',
3: 'bubble'
};
var div = document.querySelector('div');
var p = document.querySelector('p');
div.addEventListener('click', callback, true);
p.addEventListener('click', callback, true);
div.addEventListener('click', callback, false);
p.addEventListener('click', callback, false);
function callback(event) {
var tag = event.currentTarget.tagName;
var phase = phases[event.eventPhase];
console.log("Tag: '" + tag + "'. EventPhase: '" + phase + "'");
}
// 点击以后的结果
// Tag: 'DIV'. EventPhase: 'capture'
// Tag: 'P'. EventPhase: 'target'
// Tag: 'P'. EventPhase: 'target'
// Tag: 'DIV'. EventPhase: 'bubble'
上記のコードは、言ったclick
:イベントは4回トリガーされる<div>
キャプチャとバブリング段階、第一ノード、<p>
ターゲットノードステージトリガーを2回。
- 相をキャプチャ:イベントから
<div>
に<p>
伝播、トリガイベントを、<div>
click
- 対象はステージ:イベントから
<div>
到着し<p>
、トリガ<p>
のclick
イベント。 - 相をバブリング:イベントから
<p>
の復帰に<div>
再びトリガするとき、イベントを。<div>
click
どの<p>
ノードには、2つのモニター機能(持っているaddEventListener
のため、彼らがなるので、それは2つのモニター機能をバインドするためにつながる第三引数に異なる方法を)click
イベントを一度にトリガ。だから、<p>
意志のtarget
ステージは、2つの出力を有しています。
ブラウザは常に仮定することをノートclick
イベントのターゲットノードは、最も深くネストされたノードの位置をクリックすることである(この場合、ある<div>
内側ノード<p>
のノード)。したがって、<p>
キャプチャおよびバブリング段階ノードはに表示されるtarget
段階。
対象イベント伝播の上部は、window
その後に続いてdocument
、html
(document.documentElement
)およびbody
(document.body
)。換言すれば、ケースのイベント拡散のシーケンスは、キャプチャ段階するためにwindow
、document
、html
、body
、div
、p
、バブリング段階に続いてp
、div
、body
、html
、document
、window
。
イベント代理店
イベントは、ステージをバブリング親ノードまで上方に伝播されるので、サブエレメントの複数の処理リスナー関数統一イベントによって親ノードのサブノードで定義された関数、親ノードを監視することができます。この方法は、プロキシのイベント(委任)と呼ばれています。
var ul = document.querySelector('ul');
ul.addEventListener('click', function (event) {
if (event.target.tagName.toLowerCase() === 'li') {
// some code
}
});
上記のコードは、click
リスナー関数は、イベントの中で定義され<ul>
たノードが、実際に、それは子ノードを扱う<li>
のclick
イベント。これの利点は、長いリスナー関数の定義としてとして、あなたはかなりのそれぞれにおけるよりも、複数の子ノードからのイベントを処理できることである<li>
ノード上で定義されたリスナー関数。そして、後に子ノードを追加し、リスナー関数は、まだ有効です。
あなたはノード、もはや普及するまで、イベントをしたい場合は、イベントオブジェクトの使用可能stopPropagation
な方法を。
// 事件传播到 p 元素后,就不再向下传播了
p.addEventListener('click', function (event) {
event.stopPropagation();
}, true);
// 事件冒泡到 p 元素后,就不再向上冒泡了
p.addEventListener('click', function (event) {
event.stopPropagation();
}, false);
上記のコード、stopPropagation
位相を捕捉し、バブリングのメソッド、イベントの伝播を防止します。
しかし、stopPropagation
この方法は、イベントのみの伝播を防止するには、イベントトリガ妨げない<p>
他のノードがclick
イベントの機能を監視します。それは完全にキャンセルされていないclick
イベントを。
p.addEventListener('click', function (event) {
event.stopPropagation();
console.log(1);
});
p.addEventListener('click', function(event) {
// 会触发
console.log(2);
});
上記のコード、p
二つの結合素子click
モニタ機能イベント。stopPropagation
したがって、この方法は、第2のモニタ機能がトリガされます、私たちはイベントをキャンセルすることはできません、このイベントの拡散を防ぐことができます。図1は、その後、最初の2出力されます。
あなたは完全にイベントをキャンセルしたい場合は、すべての背後にはもはやトリガclick
リスナー関数は、あなたが使用することはできませんstopImmediatePropagation
方法を。
p.addEventListener('click', function (event) {
event.stopImmediatePropagation();
console.log(1);
});
p.addEventListener('click', function(event) {
// 不会被触发
console.log(2);
});
上記のコードは、stopImmediatePropagation
この方法は完全にすべての後ろに拘束さそうという、イベントをキャンセルすることができclick
なくなりましトリガされていないモニタ機能。したがって、唯一の出力1、出力2がないであろう。