Home  >  Article  >  Web Front-end  >  Summary of event streams, handlers and objects in JavaScript event learning

Summary of event streams, handlers and objects in JavaScript event learning

巴扎黑
巴扎黑Original
2017-08-16 11:13:121205browse
The interaction between JS and HTML is achieved through events. Events are specific moments of interaction that occur within a document or browser window. You can use listeners (or handlers) to schedule events so that appropriate code is executed when the event occurs. Known as the Observer pattern in traditional software engineering, this supports loose coupling between the behavior of the page and the appearance of the page. This article will introduce the basic knowledge related to JS events.
1. Event flow
The event flow describes the order in which events are received from the page.
Event bubbling
The event is initially received by the most specific element (the node with the deepest nesting level in the document), and then propagates upwards to less specific nodes (the document ). Take the following HTML page as an example. If you click a button on the page, the "click" event will be propagated in the order of 37a9605a910bf1fbe848fe3f47ab78d9, 1d6e7d87652dd104f173dbf7284e2799, 07e6e06e0dc95dc83bb70d14dca11cbe, and document. In other words, event bubbling means that the event propagates upward along the DOM tree from the underlying element that triggered the event to the document object.
<html>
 <head>
  <title>Test</title>
 </head>
 <body>
  <button id="myBtn">A Btn</button>
 </body>
</html>

Event capture
Contrary to the idea of ​​event bubbling, the idea of ​​event capture is that less specific nodes should receive events earlier, and the most specific nodes should Events are received last. Still in the above example, after clicking the button on the page, the "click" event will be propagated in the order of document, 07e6e06e0dc95dc83bb70d14dca11cbe, 1d6e7d87652dd104f173dbf7284e2799, 37a9605a910bf1fbe848fe3f47ab78d9. In other words, event capture means that the event propagates downwards along the DOM tree from the document object until the actual target element of the event.
DOM event flow
The events specified by "DOM2-level events" include three stages: event capture stage, target stage and event bubbling stage. The first thing that happens is event capture, which provides the opportunity to intercept the event. Then the actual target receives the event. The final phase is the bubbling phase, where you can respond to events.
Still taking the previous button click as an example, in the DOM event flow, during the capture phase, the "click" event starts from the document and is passed down to the body element (note that the actual target button will not receive the event during the capture phase). In the target phase, the button element receives the "click" event. Finally, in the bubbling phase, the event is propagated back to the document.
2. Event handler
An event is a certain action performed by the user or the browser itself, and the function that responds to an event is called an event handler or event listener.
HTML event handler
The HTML event handler here refers to the event handler defined directly in the HTML element through the attribute (attribute), please see the following code example. In this case, the event handler will create a function that encapsulates the element's attribute value, and this value is equal to the target element of the event. Specifying event handlers in this way has several disadvantages and is not recommended.
<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>

DOM0 level event handler
The traditional way to specify an event handler through JS is to assign a function to an event handler attribute, please see the following code example. Event handlers specified this way run within the scope of the element, with this referring to the current element. Event handlers added in this way will be processed during the bubbling phase of the event flow. If you want to delete the event, just set the value of onclick to empty.
var btn = document.getElementById("myBtn");
btn.onclick = function() {
 console.log("this.id"); // "myBtn"
};
// 删除事件处理程序
btn.onclick = null;

DOM2-level event handler
"DOM2-level event" defines two methods for specifying and removing event handlers, addEventListener() and removeEventListener(). These two methods are included in all DOM nodes. Both methods receive 3 parameters, the event to be processed, the processing function, and the Boolean value. The final Boolean value means that the event handler is called during the capture phase when true, and false when the event handler is called during the bubbling phase. Like the DOM0-level methods, the event handler added here also runs in the scope of the element to which it is attached. The advantage of adding event handlers using the DOM2-level method is that you can add multiple event handlers. These event handlers are fired in the order they were added. The following is a code example:
var btn = document.getElementById("myBtn");
// 添加,触发点击事件时先输出"myBtn"再输出"HaHa~"
btn.addEventListener("click", function() {
 console.log(this.id);
}, false);
btn.addEventListener("click", function() {
 console.log("HaHa~");
}, false);

Events added through addEventListener() can only be removed through removeEventListener(). The parameters passed in when deleting should be consistent with the parameters used when adding. This also means that the anonymous function added through addEventListener() cannot be deleted, because the anonymous function passed when adding cannot be passed to removeEventListener(). Even if an identical function is written when deleting, this function is just a New anonymous function. Please see the following code example:
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);

In most cases, event handlers are added to the bubbling phase of the event flow, so as to maximize compatibility with various browsers. It is best to add event handlers to the capture phase only when you need to intercept the event before it reaches the target. The advice given in JS advanced programming is that if it is not specifically needed, it is not recommended to register an event handler in the event capture phase.
IE event handler
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);

三、事件对象
在触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含着所有与事件有关的信息,包括导致事件的元素、事件的类型以及其他与特定事件相关的信息。
DOM中的事件对象
兼容DOM的浏览器会将一个event对象传入事件处理程序中,无论指定事件处理程序时用的是DOM0还是DOM2的方法,都会传入event对象。event对象只有在事件处理程序执行期间才会存在,一旦事件处理程序执行完毕,event对象就会被销毁。下面是代码示例:
var btn = document.getElementById("myBtn");
btn.onclick = function(event) {
 console.log(event.type); // "click"
}
btn.addEventListener("click", function(event) {
 console.log(event.type);
}, false);

event对象包含与创建它的特定事件有关的属性和方法,触发的事件类型不一样,可用的属性方法也有所不同。但是所有的事件都会有下列的属性或方法:
bubbles: 布尔值,表示事件是否冒泡
cancelable: 布尔值,表示是否可以取消事件的默认行为
currentTarget: 元素,事件处理程序当前正在处理事件的那个元素
defaultPrevented: 布尔值,表示是否调用过preventDefault()方法
detail: 整数,与事件相关的细节信息
eventPhase: 整数,调用事件处理程序的阶段,1表示捕获阶段,2表示目标阶段,3表示冒泡阶段
preventDefault(): 函数,取消事件的默认行为,cancelable为true时可以调用该方法
stopImmediatePropagation(): 函数,取消事件的进一步捕获或冒泡,同时阻止任何事件处理程序被调用
stopPropagation(): 函数,取消事件的进一步捕获或冒泡,bubbles为true时可以调用这个方法
target: 元素,事件的目标
trusted: 布尔值,为true时表示事件是浏览器生成的,否则表示事件是通过JS创建的
type: 字符串,被触发的事件类型
view: 与事件关联的抽象视图,等同于发生事件的window对象
下面代码示例展示了上述部分属性的用法,也可以帮助我们进一步理解事件流。假设页面中有一个按钮”myBtn”。当点击按钮时,this和currentTarget都等于body元素,因为事件处理程序是注册在body元素上。target的值却等于按钮元素,因为它是click事件的真正目标。由于按钮上没有注册事件处理程序,结果”click”事件冒泡到了document.body那里才得到处理。
document.body.onclick = function(event) {
 console.log(event.currentTarget === document.body); // true
 console.log(this === document.body); // true
 console.log(event.target === document.getElementById("myBtn")); // true
};

再看一个例子,下面代码中,stopPropagation()方法取消了事件的进一步捕获或冒泡。当我点击按钮时,本来应该会因为事件冒泡机制触发按钮和body元素上的点击事件处理程序,输出”From Bth …”和”From Body …”。现在点击事件在按钮元素上触发之后就被阻止继续在DOM层次中的传播,因此body上的事件处理程序不会被触发。
var btn = document.getElementById("myBtn");
btn.onclick = function(event) {
 console.log("From Bth ...");
 event.stopPropagation(); // 停止事件传播
};
document.body.onclick = function() {
 console.log("From Body ...");
};

IE中的事件对象
在IE中,使用DOM0的方法添加事件处理程序时,event对象作为window对象的一个属性存在。如果是通过attachEvent()方法添加,则event对象是作为参数传入事件处理函数。下面是代码示例:
var btn = document.getElementById("myBtn");
btn.onclick = function() {
 var event = window.event;
 console.log(event.type); // "click"
};
btn.attachEvent("onclick", function(event) {
 console.log(event.type); // "click"
});

IE的event对象同样也包含与创建它的事件相关的属性和方法,这些属性和方法也会因为事件类型的不同而有所差异。但所有事件对象都会包含下列属性:
cancelBubble: 布尔值,可读可写,默认为false。将其设置为true时取消事件冒泡
returnValue: 布尔值,可读可写,默认为true。将其设置为false时取消事件的默认行为
srcElment: 元素,事件的目标元素,与DOM中的target属性相同
type: 字符串,事件类型
在IE中,事件处理程序的作用域是根据指定它的方式来确定,this的值不一定是指向事件的目标元素。因此,使用srcElement属性更具保险。请看下面代码实例,第一种方式中this的值为目标元素,而第二种方式,前面讲过这种方式的事件处理程序是在全局作用域中执行,因此this的值为window。
var btn = document.getElementById("myBtn");
btn.onclick = function() {
 console.log(window.event.srcElement === this); // true
}
btn.attachEvent("onclick", function(event) {
 console.log(event.srcElement === this); // false
});

The above is the detailed content of Summary of event streams, handlers and objects in JavaScript event learning. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn