Original sentence: Https://Wangdoc.Com/javascript/index.Html
Event Model
Monitor function
Event model browser, that is, by listening function (listener) react to events. After the incident, the browser listens to this event, will monitor the implementation of the corresponding function. This is the main way of programming event-driven programming model (event-driven) of.
JavaScript There are three ways you can bind a function to listen for the event.
HTML attribute of on-
HTML language allows the attribute of the element, the code defined directly monitor certain events.
<body onload="doSomething()">
<div onclick="console.log('触发事件')">
The above code body
node of load
the event, div
node click
event, designated listener code. Once the event occurs, it will execute the code.
Event monitor element attributes are on
coupled with the event name, such as onload
is on + load
expressed load
listens code for the event.
Note that the values of these properties will execute the code, rather than a function.
<!-- 正确 -->
<body onload="doSomething()">
<!-- 错误 -->
<body onload="doSomething">
Once a specified event occurs, the on-
value of the property as it is passed in the implementation of the JavaScript engine. So if you want to perform a function, do not forget to add a pair of parentheses.
Use this method to specify a monitor code will only trigger in the bubbling phase.
<div onClick="console.log(2)">
<button onClick="console.log(1)">点击</button>
</div>
The above code, <button>
is a <div>
child element. <button>
The click
event will trigger <div>
the click
event. Due to on-
the properties of the monitor code is only triggered in the bubbling phase, so click on the first result is output 1
, and then output 2
that events from child elements began to bubble to the parent element.
Directly on-
properties, and by the element node setAttribute
setting method on-
attribute, the effect is the same.
el.setAttribute('onclick', 'doSomething()');
// 等同于
// <Element onclick="doSomething()">
Event attributes of an element node
Event attribute element node object can also specify the listener function.
window.onload = doSomething;
div.onclick = function (event) {
console.log('触发事件');
};
Use this method to specify the listener function is only triggered in the bubbling phase.
Note that this approach HTML- on-
difference property is, its value is the function name ( doSomething
), unlike the latter, the code must be given full listen ( doSomething()
).
EventTarget.addEventListener()
All DOM node instance has addEventListener
a method used to define the event listener function for the node.
window.addEventListener('load', doSomething, false);
addEventListener
Details of the method, see EventTarget
chapter.
summary
The above three methods, the first "HTML attribute of on-" violated the principle of HTML and JavaScript code separate from, the two write together, is not conducive to the code division of labor, and therefore not recommended.
The second drawback "event attribute element nodes" that can define a listener function the same event, that is, if you define two onclick
properties, after a pre-defined time coverage. Therefore, not recommended.
The third EventTarget.addEventListener
is to specify the listener function method is recommended. It has the following advantages:
- Same event listeners can add multiple functions.
- The ability to specify at what stage (capture phase or the bubbling phase) trigger monitor function.
- In addition to DOM nodes, other objects (for example
window
,XMLHttpRequest
etc.) also have this interface, which is tantamount to monitor the entire unified JavaScript function interface.
this point
Internal monitor function this
points to trigger events that element node.
<button id="btn" onclick="console.log(this.id)">点击</button>
The implementation of the above code, the output will click btn
.
Other written two on duration function, this
the point is 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
);
Both spelling variants, after clicking the button is output btn
.
Propagation of an event
After an event occurs, the spread (propagation) between child elements, and parent elements. This propagation is divided into three stages.
- The first stage : the
window
conductive object to the target node (upper layer reached the bottom layer), referred to as "capture phase" (capture phase). - The second stage : on the target node triggers, known as the "target phase" (target phase).
- The third stage : from the target node back conductive
window
object (returned from the bottom layer), referred to as "bubble phase" (bubbling phase).
This three-stage propagation model, making the same event triggers on multiple nodes.
<div>
<p>点击</p>
</div>
In the above code, <div>
among the nodes have a <p>
node.
If these two nodes are set to click
monitor the function of events (capture and bubbling phases each node, each set up a monitor function), set up a total of four monitor functions. Then, <p>
click click
the event will trigger four times.
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'
The code above said click
events are triggered four times: <div>
the capture and bubbling phases, the 1st node, <p>
the target node stage trigger twice.
- Capturing phase: from event
<div>
to<p>
propagation, triggered<div>
theclick
event; - Target stages: from the event
<div>
arrives<p>
, the triggering<p>
ofclick
events; - Bubbling phase: from event
<p>
to return<div>
when once again trigger<div>
theclick
event.
Which <p>
node has two monitor function ( addEventListener
different ways to the third argument, it will lead to bind the two monitor function), so they will be because of click
events triggered once. So, <p>
will target
stage has two outputs.
Note that the browser always assume click
the target node of the event, is to click on the location of the most deeply nested nodes (in this case is a <div>
node inside the <p>
node). Therefore, <p>
the capture and bubbling phases nodes will be displayed for the target
stage.
Top of an object event propagation is window
then followed by document
, html
( document.documentElement
) and body
( document.body
). In other words, the sequence of events spread of cases, in order to capture phase window
, document
, html
, body
, div
, p
, in the bubbling phase followed p
, div
, body
, html
, document
, window
.
Event agency
Since the event is propagated upwardly to the parent node bubbling stage, it is possible to monitor the function defined in the sub-node on the parent node, the parent node by a listener function unified event processing a plurality of sub-elements. This method is called proxy events (delegation).
var ul = document.querySelector('ul');
ul.addEventListener('click', function (event) {
if (event.target.tagName.toLowerCase() === 'li') {
// some code
}
});
The above code, click
the listener function is defined in the event of <ul>
a node, but in fact, it deals with the child node <li>
of the click
event. The advantage of this is that as long as the definition of a listener function, you can handle events from multiple child nodes, rather than in each of the <li>
defined listener function on the node. And then later add a child node, the listener function is still valid.
If you want the event until a node, no longer spread, you can use the event object's stopPropagation
methods.
// 事件传播到 p 元素后,就不再向下传播了
p.addEventListener('click', function (event) {
event.stopPropagation();
}, true);
// 事件冒泡到 p 元素后,就不再向上冒泡了
p.addEventListener('click', function (event) {
event.stopPropagation();
}, false);
The above code, stopPropagation
Methods in capturing and bubbling phases, preventing the propagation of an event.
However, the stopPropagation
method will only prevent propagation of an event, it does not prevent the event trigger <p>
other nodes click
monitor the function of the event. That is not completely cancel the click
event.
p.addEventListener('click', function (event) {
event.stopPropagation();
console.log(1);
});
p.addEventListener('click', function(event) {
// 会触发
console.log(2);
});
The above code, the p
element binding the two click
monitor function events. stopPropagation
The method can prevent the spread of this event, we can not cancel the event, therefore, the second monitor function will be triggered. 1 will be output first, then 2.
If you want to completely cancel the event, no longer triggers all behind click
the listener function, you can use stopImmediatePropagation
the method.
p.addEventListener('click', function (event) {
event.stopImmediatePropagation();
console.log(1);
});
p.addEventListener('click', function(event) {
// 不会被触发
console.log(2);
});
The above code, stopImmediatePropagation
the method can completely cancel the event, so that all bound behind click
monitor functions are no longer triggered. Therefore, the only output 1, output 2 will not.