javascript: Event Model

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 bodynode of loadthe event, divnode clickevent, designated listener code. Once the event occurs, it will execute the code.

Event monitor element attributes are oncoupled with the event name, such as onloadis on + loadexpressed loadlistens 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 clickevent will trigger <div>the clickevent. 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 2that events from child elements began to bubble to the parent element.

Directly on-properties, and by the element node setAttributesetting 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 addEventListenera method used to define the event listener function for the node.

window.addEventListener('load', doSomething, false);

addEventListenerDetails of the method, see EventTargetchapter.

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 onclickproperties, after a pre-defined time coverage. Therefore, not recommended.

The third EventTarget.addEventListeneris 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, XMLHttpRequestetc.) also have this interface, which is tantamount to monitor the entire unified JavaScript function interface.

this point

Internal monitor function thispoints 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, thisthe 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 windowconductive 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 windowobject (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 clickmonitor 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 clickthe 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 clickevents are triggered four times: <div>the capture and bubbling phases, the 1st node, <p>the target node stage trigger twice.

  1. Capturing phase: from event <div>to <p>propagation, triggered <div>the clickevent;
  2. Target stages: from the event <div>arrives <p>, the triggering <p>of clickevents;
  3. Bubbling phase: from event <p>to return <div>when once again trigger <div>the clickevent.

Which <p>node has two monitor function ( addEventListenerdifferent ways to the third argument, it will lead to bind the two monitor function), so they will be because of clickevents triggered once. So, <p>will targetstage has two outputs.

Note that the browser always assume clickthe 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 targetstage.

Top of an object event propagation is windowthen 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, clickthe listener function is defined in the event of <ul>a node, but in fact, it deals with the child node <li>of the clickevent. 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 stopPropagationmethods.

// 事件传播到 p 元素后,就不再向下传播了
p.addEventListener('click', function (event) {
  event.stopPropagation();
}, true);

// 事件冒泡到 p 元素后,就不再向上冒泡了
p.addEventListener('click', function (event) {
  event.stopPropagation();
}, false);

The above code, stopPropagationMethods in capturing and bubbling phases, preventing the propagation of an event.

However, the stopPropagationmethod will only prevent propagation of an event, it does not prevent the event trigger <p>other nodes clickmonitor the function of the event. That is not completely cancel the clickevent.

p.addEventListener('click', function (event) {
  event.stopPropagation();
  console.log(1);
});

p.addEventListener('click', function(event) {
  // 会触发
  console.log(2);
});

The above code, the pelement binding the two clickmonitor function events. stopPropagationThe 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 clickthe listener function, you can use stopImmediatePropagationthe method.

p.addEventListener('click', function (event) {
  event.stopImmediatePropagation();
  console.log(1);
});

p.addEventListener('click', function(event) {
  // 不会被触发
  console.log(2);
});

The above code, stopImmediatePropagationthe method can completely cancel the event, so that all bound behind clickmonitor functions are no longer triggered. Therefore, the only output 1, output 2 will not.

Guess you like

Origin www.cnblogs.com/wbyixx/p/12499287.html