Home  >  Article  >  Web Front-end  >  Detailed explanation of event model in JavaScript (code example)

Detailed explanation of event model in JavaScript (code example)

不言
不言forward
2018-11-21 11:47:411597browse
This article brings you a detailed explanation (code example) of the event model in JavaScript. It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.

event

The interaction between users and web pages is realized through events. Events were initially used as a means to share server load. At first, there was no unified specification. It was not until the DOM2 level that Netscape and IE began to have their own API specifications.

Regarding the event triggering mechanism, both companies believe that the triggering mechanism of the page does not only trigger the event of the current target element when a certain element is clicked.

For example: the page has multiple concentric circles. When you click on the innermost circle, you actually click on the circles that include the outside of this circle. The two companies agree on this point, but the propagation sequence of the event stream is implemented using two different solutions, namely event bubbling and event capture.

1. Event bubbling

IE browser has always supported the event bubbling mechanism since the old version. The so-called event bubbling means that the event stream starts from a more specific element and continues to On dissemination of non-specific elements.

is propagated from the target element to the parent element.

    <div>
        <div></div>
    </div>
    <script>
    function childEventHandler(event) {
        console.log(this);
        console.log("child 被点击了");
    }
    function parentEventHandler(event) {
        console.log(this);
        console.log("parent 被点击了");
    }
    function bodyEventHandler(event) {
        console.log(this);
        console.log("body 被点击了");
    }
    function htmlEventHandler(event) {
        console.log(this);
        console.log("html 被点击了");
    }
    function documentEventHandler(event) {
        console.log(this);
        console.log("document 被点击了");
    }
    function windowEventHandler(event) {
        console.log(this);
        console.log("window 被点击了");
    }
    var bodyEl = document.getElementsByTagName("body")[0];
    var htmlEl = document.getElementsByTagName("html")[0];
    var win = window;
    var parentEl = document.getElementById("parent");
    var childEl = document.getElementById("child");
    childEl.onclick = childEventHandler;
    parentEl.onclick = parentEventHandler;
    bodyEl.onclick = bodyEventHandler;
    htmlEl.onclick = htmlEventHandler;
    document.onclick = documentEventHandler;
    win.onclick = windowEventHandler;
    </script>

As shown in the figure below, if you click on the element with the id of child, the event flow will propagate from the child to the window object.

Detailed explanation of event model in JavaScript (code example)

Detailed explanation of event model in JavaScript (code example)

##All modern browsers support event bubbling.

2. Event Capture

Event capture led by Netscape is just the opposite of event bubbling. The event stream starts to be triggered from unspecific elements and then spreads to specific elements. In short, it is propagated from the parent element to the target element.

Detailed explanation of event model in JavaScript (code example)

Since event capture is supported from IE 9 and is not compatible with older versions of browsers, fewer people use it.

3. Event flow

DOM stipulates that events include three stages: event capture, target stage, and event bubbling.

Browsers starting from IE 9 stipulate that the order of event flow is event capture first, the event will be intercepted, then it is in the target stage, the actual target receives the event, and finally the event bubbles up. You can check this Stage responds to events.

Taking the previous child element as an example, until the child element receives the event (from window to parent), it is the event capture stage. When it comes to the child element, the event is processed at this time, and then bubbles to the window object. The event can also be processed during the bubbling stage. Based on the characteristics of event bubbling that can process events, the event delegation mechanism related to it will be discussed later.

Detailed explanation of event model in JavaScript (code example)

4. Event Binding

There are three forms of binding between HTML and events:

1. 
<div></div>

2. 

var childEl = document.getElementById("child");
childEl.onclick = function() {
    console.log('hello');
}

3. 
var childEl = document.getElementById("child");
childEl.addEventListener('click', function() {
    console.log('hello');
}, false);
JavaScript It is a single-threaded language. When an event is triggered on an element, it will search the event queue to see if there is a function bound to the event. If there is not, it will do nothing. If there is, the function will be placed in the event queue. In front of, wait for the main thread event to be executed after execution.

The first binding of the above code writes the event in html, and the performance and behavior are not decoupled. It is not recommended to write code in this way.

The second type of binding binds events to element objects. This writing method is mainly easy to overwrite events.

The third binding, first of all, the third parameter is a Boolean value, the default is false, which means that the event handler is called in the event bubbling stage. If it is true, it means that the event handler is called in the event capture stage. function.

When we want to process an event and do not want to process the event binding of the element, we should set the event binding of the element to empty, if memory leaks are prone to occur.

第一种写法:
childEl.onclick = null;


第三种写法:
function eventHandler() {
    console.log('hello');
}

childEl.addEventListener('click', eventHandler, false);

childEl.removeEventListener('click', eventHandler, false);
5. Event delegation (event proxy)

Event delegation takes advantage of the nature of event bubbling. The event stream starts from receiving more specific elements and continues to spread to unspecific elements. .

First of all, if there is a list ul, each list element li click will trigger the event handler. Obviously, if you bind events to the elements one by one, the efficiency will definitely not be good.

At the same time, when a new element is added, the event may not be bound successfully. Let’s take a look at it together:


        
  • menu-1
  •     
  • menu-2
  •     
  • menu-3
  •     
  • menu-4
<script> window.onload = function() { var menu = document.getElementById("menu"); var item = menu.getElementsByClassName(&#39;menu-item&#39;); for (var i = 0; i < item.length; i++) { item[i].onclick = (function(i) { return function() { console.log(i); } }(i)) } var addBtnEl = document.getElementById("addBtn"); addBtnEl.onclick = function() { var newEl = document.createElement(&#39;li&#39;); newEl.innerHTML = "menu-new" menu.appendChild(newEl); } } </script> When clicking on the newly added menu-new, there is no response, indicating that the event is not bound to it, but we do not want to bind the event to this new element every time a new element is added. , repeating inefficient work should be avoided.

我们通过事件委托的思路来想,事件流的传播,目标元素本身依然会有事件,但同时,冒泡出去后,更高层次的 dom 也能处理事件程序。那么,我们只需要给高层次节点绑定事件,通过判断具体是触发的哪个子节点,再做相应的事件处理。


        
  • menu-1
  •     
  • menu-2
  •     
  • menu-3
  •     
  • menu-4
<script> window.onload = function() { var menu = document.getElementById("menu"); menu.onclick = function(event) { var e = event || window.event; var target = e.target || e.srcElement; console.log(e); switch (target.textContent) { case "menu-1": console.log("menu-1 被点击了"); break; case "menu-2": console.log("menu-2 被点击了"); break; case "menu-3": console.log("menu-3 被点击了"); break; case "menu-4": console.log("menu-4 被点击了"); break; case "menu-new": console.log("menu-new 被点击了"); break; } } var addBtnEl = document.getElementById("addBtn"); addBtnEl.onclick = function() { var newEl = document.createElement(&#39;li&#39;); newEl.innerHTML = "menu-new" menu.appendChild(newEl); } } </script>

menu 列表的每个子菜单元素的事件都能正确响应,新增的 menu-new 同样也能正确响应事件。

事件委托的好处在于,我们不用给每个元素都一一地手动添加绑定事件,避免重复低效的工作。

其次,事件委托更少得获取 dom, 初始化元素对象和事件函数,能有效减少内存占用。

每当将事件程序指定给元素时,html 代码和 js 代码之间就建立了一个连接,这种连接越多,网页就执行起来越慢,所以事件委托能有效减少连接树,提高网页性能。

总结

用户与网页的交互是通过事件进行的,事件模型分为事件冒泡和事件捕获,事件冒泡的兼容性更好,应用更广,同时通过事件冒泡,可以建立事件委托,提升网页性能。

The above is the detailed content of Detailed explanation of event model in JavaScript (code example). For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:segmentfault.com. If there is any infringement, please contact admin@php.cn delete