JavaScipt Ninja Cheats page of the runtime of the build process

Life Cycle Overview

A typical client Web application life cycle from user input string URL in the browser address bar, or click on a link to begin:

From the user's point of view:

Construction of a browser request to the server (No. 2), the server processing the request (No. 3) and forms a response usually consists of HTML, CSS and JavaScript code consisting of;

When the browser receives the response (No. 4), our client application begins its life cycle.

Because the client Web application is a graphical user interface (GUI) applications, its life cycle is similar to other GUI applications (e.g., standard desktop applications or mobile applications), which performs the following steps:

1. Page builder - Create a user interface;

2. Event processing - into the circulation (No. 5) so as to wait for occurrence of an event (sequence number 6), after the occurrence of the event handler invoked.

Life cycle of the application with the user to switch off or leave the page (No. 7) and ends.

<!DOCTYPE html>
<html>
    <head>
        <title>Web app lifecycle</title>
        <style>
            #first { color: green;}
            #second { color: red;}
        </style>
    </head>
    <body>
        
        <ul id="first"> </ul>
        
        <script>
            function addMessage(element, message){
                var messageElement = document.createElement("li");
                messageElement.textContent = message;
                element.appendChild(messageElement);
            } //<--- 定义一个函数用于向一个元素增加一条信息
            var first = document.getElementById("first");
            addMessage(first, "Page loading");
        </script>
        <ul id="second"> </ul>
        <script>
            document.body.addEventListener("mousemove", function() {
                //---为body附上鼠标移动事件处理函数
                var second = document.getElementById("second");
                addMessage(second, "Event: mousemove");
            });
                //为body附上鼠标点击事件处理函数
            document.body.addEventListener("click", function(){ 
                var second = document.getElementById("second");
                addMessage(second, "Event: click");
            });
    </script>
    </body>
</html>                                              

It defines two CSS rules that #first and #second, which specifies the text color ID for the first and second two elements (so that we easily distinguish between the two regions). Then define a list of elements with this first id:

<ul id="first"></ul>

AddMessage then define a function, every time the function is called creates a new entry element to set the text content, and then attach it to an existing element:

function addMessage(element, message){
    var messageElement = document.createElement("li");
    messageElement.textContent = message;
    element.appendChild(messageElement);
}

getElementById to get the ID for the first element by using the built-in method from the document, and then add a message for the element that tells the page is loading:

var first = document.getElementById("first");
addMessage(first, "Page loading");

Then we define the elements of a list, the list given to the ID attribute is second:

<ul id="second"></ul>

Finally, these two event handlers attached to the body Web page. Whenever the user moves the mouse, move the mouse event handler is executed, then the processor calls addMessage method, for the second list element plus the word "Event: mousemove".

document.body.addEventListener("mousemove", function() {
    var second = document.getElementById("second");
    addMessage(second, "Event: mousemove");
});

Also registered a click event handler whenever the user clicks the page will output the message "Event: click", and added to the second list element.

document.body.addEventListener("click", function(){
    var second = document.getElementById("second");
    addMessage(second, "Event: click");
});

Page Construction Phase

Before the Web application can be displayed or interaction, it must be built according to the response page (usually HTML, CSS and JavaScript code) server acquired. Page build target stage is to establish a UI Web application, which involves two main steps:

1. Parses the HTML code and build the Document Object Model (DOM);

2. Execute JavaScript code.

HTML parsing and DOM building

Construction phase begins when the page the browser receives the HTML code, the stage of building the foundation for the browser UI page. By parsing the HTML code received to construct one HTML element, constructed DOM. In this form of the HTML representation of the structure, each HTML element is treated as a node. As shown, until the first script element, sample pages are constructed DOM.

Note how the nodes in the graph is organized, in addition to the first root node --html (No. 1), all the nodes have only one parent node.

For example, (No. 2) parent html head node is the node (No. 1). At the same time, a node can have any number of child nodes. For example, html node (No. 1) has two children nodes: head node (No. 2) and a body node. The child node of the same element are called sibling nodes. (Head and body node node is a sibling) Although DOM is based on HTML to create, the two are closely linked, but needs to be emphasized is that they both are not the same. You can put HTML code is regarded as a browser page DOM UI to build the initial blueprint. To build each DOM correctly, the browser will fix problems it finds in the blueprint. Let's look at the following example, as shown in Fig.

In the construction phase the page, the browser will encounter special type of HTML elements - script element, which used to include JavaScript code. Whenever resolve to script elements, the browser will stop building the DOM HTML, and begin to execute JavaScript code.


JavaScript code execution

Global object in JavaScript

The main browser JavaScript engine exposed to the global object is the window object , which represents the window contains a page.

window对象是获取所有其他全局对象、全局变量(甚至包含用户定义对象)和浏览器API的访问途径。

​ 全局window对象最重要的属性是document,它代表了当前页面的DOM。

​ 通过使用这个对象,JavaScript代码就能在任何程度上改变DOM,包括修改或移除现存的节点,以及创建和插入新的节点。

var first = document.getElementById("first");

​ 使用全局document对象来通过ID选择一个元素,然后将该元素赋值给变量first。

​ 随后我们就能在该元素上用JavaScript代码来对其作各种操作,例如改变其文字内容,修改其属性,动态创建和增加新孩子节点,甚至可以从DOM上将该元素移除。

JavaScript代码的不同类型

​ 区分出两种不同类型的JavaScript代码:全局代码函数代码

<script>
    function addMessage(element, message){
        var messageElement = document.createElement("li");
        messageElement.textContent = message;  //--- 函数代码指的是包含在函数中的代码
        element.appendChild(messageElement);
    }
    var first = document.getElementById("first");
    addMessage(first, "Page loading"); //--- 全局代码指的是位于函数之外的代码
</script>

​ 这两类代码的主要不同是它们的位置:包含在函数内的代码叫作函数代码,而在所有函数以外的代码叫作全局代码。

​ 全局代码由JavaScript引擎(后续会做更多解释)以一种直接的方式自动执行,每当遇到这样的代码就一行接一行地执行。

​ 例如,定义addMessage函数的全局代码片段使用内置方法getElementById来获取ID为first的元素,然后再调用addMessage函数,如图所示,每当遇到这些代码就会一个个执行。

​ 反过来,若想执行函数代码,则必须被其他代码调用:既可以是全局代码(例如,由于全局代码的执行过程中执行了addMessage函数代码,所以addMessage函数被调用),也可以是其他函数,还可以由浏览器调用。

在页面构建阶段执行JavaScript代码

​ 当浏览器在页面构建阶段遇到了脚本节点,它会停止HTML到DOM的构建,转而开始执行JavaScript代码,也就是执行包含在脚本元素的全局JavaScript 代码 (以及由全局代码执行中调用的函数代码)。

​ 在全局JavaScript代码被执行后DOM的状态。让我们仔细看看这个执行过程。首先定义了一个addMessage函数:

function addMessage(element, message){
    var messageElement = document.createElement("li");
    messageElement.textContent = message;
    element.appendChild(messageElement);
}

​ 然后通过全局document对象上的getElementById方法从DOM上获取了一个元素:

var first = document.getElementById("first");

​ 这段代码后紧跟着对函数addMessage 的调用:

addMessage(first, "Page loading");

​ 这条代码创建了一个新的li元素,然后修改了其中的文字内容,最后将其插入 DOM中。

​ 这个例子中,JavaScript通过创建一个新元素并将其插入DOM节点修改了当前的DOM结构。一般来说,JavaScript 代码能够在任何程度上修改DOM结构:

​ 它能创建新的节点或移除现有DOM节点。

​ 但它依然不能做某些事情,例如选择和修改还没被创建的节点。

​ 这就是为什么要把script元素放在页面底部的原因。如此一来,我们就不必担心是否某个HTML元素已经加载为DOM。

​ 一旦JavaScript引擎执行到了脚本元素中(如上图中的addMessage函数返回)JavaScript代码的最后一行,浏览器就退出了JavaScript执行模式,并继续余下的HTML构建为DOM节点。在这期间,如果浏览器再次遇到脚本元素,那么从HTML到DOM的构建再次暂停,JavaScript运行环境开始执行余下的JavaScript代码。

​ 需要重点注意:

​ JavaScript应用在此时依然会保持着全局状态。

​ 所有在某个JavaScript代码执行期间用户创建的全局变量都能正常地被其他脚本元素中的JavaScript代码所访问到。

​ 其原因在于全局window对象会存在于整个页面的生存期之间,在它上面存储着所有的JavaScript变量。

​ 只要还有没处理完的HTML元素和没执行完的JavaScript代码,下面两个步骤都会一直交替执行。

​ 1.将HTML构建为DOM。
​ 2.执行JavaScript代码。

​ 最后,当浏览器处理完所有HTML元素后,页面构建阶段就结束了


事件处理

事件处理器概览

浏览器执行环境的核心思想基于:==同一时刻只能执行一个代码片段,即所谓的单线程执行模型。==

事件处理的过程可以描述为一个简单的流程图:

​ 浏览器检查事件队列头;
​ 如果浏览器没有在队列中检测到事件,则继续检查;
​ 如果浏览器在队列头中检测到了事件,则取出该事件并执行相应的;
​ 事件处理器(如果存在)。在这个过程中,余下的事件在事件队列中耐心等待,直到轮到它们被处理。

由于一次只能处理一个事件,所以我们必须格外注意处理所有事件的总时间。执行需要花费大量时间执行的事件处理函数会导致Web应用无响应!

​ 重点注意浏览器在这个过程中的机制,其放置事件的队列是在页面构建阶段和事件处理阶段以外的。

​ 这个过程对于决定事件何时发生并将其推入事件队列很重要,这个过程不会参与事件处理线程。


事件是异步的

​ 事件可能会以难以预计的时间和顺序发生(强制用户以某个顺序按键或单击是非常奇怪的)。我们对事件的处理,以及处理函数的调用是异步的。如下类型的事件会在其他类型事件中发生。

  • 浏览器事件,例如当页面加载完成后或无法加载时;
  • 网络事件,例如来自服务器的响应(Ajax事件和服务器端事件);
  • 用户事件,例如鼠标单击、鼠标移动和键盘事件;
  • 计时器事件,当timeout时间到期或又触发了一次时间间隔。

​ 事件处理的概念是Web应用的核心,代码的提前建立是为了在之后的某个时间点执行。除了全局代码,页面中的大部分代码都将作为某个事件的结果执行。
​ 在事件能被处理之前,代码必须要告知浏览器我们要处理特定事件.


注册事件处理器

事件处理器是==当某个特定事件发生后我们希望执行的函数。==为了达到这个目标,我们必须告知浏览器我们要处理哪个事件。这个过程叫作注册事件处理器

​ 在客户端Web应用中,有两种方式注册事件。

  • 通过把函数赋给某个特殊属性;
  • 通过使用内置addEventListener方法。

​ 将一个函数赋值给window对象上的某个特定属性onload:

window.onload = function(){};

​ 通过这种方式,事件处理器就会注册到load事件上(当DOM已经就绪并全部构建完成,就会触发这个事件)。

​ 如果我们想要为在文档中body元素的单击事件注册处理器,我们可以输入下述代码:

document.body.onclick = function(){};

​ 把函数赋值给特殊属性是一种简单而直接的注册事件处理器方式。

​ 但是,我们并不推荐你使用这种方式来注册事件处理器,这是因为这种做法会带来缺点:对于某个事件只能注册一个事件处理器。也就是说,一不小心就会将上一个事件处理器改写掉。

​ 幸运的是,还有一种替代方案:addEventListener方法让我们能够注册尽可能多的事件,只要我们需要.

<script>
    //--- 为mousemove事件注册处理器
    document.body.addEventListener("mousemove", function() { 
        var second = document.getElementById("second");
        addMessage(second, "Event: mousemove");
    });
    //-- 为click事件注册处理器
    document.body.addEventListener("click", function(){ 
        var second = document.getElementById("second");
        addMessage(second, "Event: click");
    });
</script>

​ 本例中使用了某个HTML元素上的内置的方法addEventListener,并在函数中指定了事件的类型(mousemove事件或click)和事件的处理器。

​ 这意味着当鼠标在页面上移动后,浏览器会调用该函数添加一条消息到ID为second的list元素上,"Event: mousemove"(类似,当body被单击时,"Event: click"也会被添加到同样的元素上)。


处理事件

  • 事件处理背后的主要思想是:==当事件发生时,浏览器调用相应的事件处理器。==
  • 如前面提到的,由于单线程执行模型,所以同一时刻只能处理一个事件。
  • 任何后面的事件都只能在当前事件处理器完全结束执行后才能被处理!

展示了在用户快速移动和单击鼠标时的执行情况。

​ 为了响应用户的动作,浏览器把鼠标移动和单击事件以它们发生的次序放入事件队列:

  1. 第一个是鼠标移动事件,第二个是单击事件序号1。
  2. 在事件处理阶段中,事件循环会检查队列,其发现队列的前面有一个鼠标移动事件,然后执行了相应的事件处理器序号2。
  3. 当鼠标移动事件处理器处理完毕后,轮到了等待在队列中的单击事件。当鼠标移动事件处理器函数的最后一行代码执行完毕后,JavaScript引擎退出事件处理器函数,鼠标移动事件完整地处理了序号3,事件循环再次检查队列。这一次,在队列的最前面,事件循环发现了鼠标单击事件并处理了该事件。
  4. 一旦单击处理器执行完成,队列中不再有新的事件,事件循环就会继续循环,等待处理新到来的事件。
  5. 这个循环会一直执行到用户关闭了Web应用。

  1. 执行鼠标移动处理器时会选择第二个列表元素,其ID为second。
  2. 然后通过使用addMessage,使用文字“Event: mousemove”添加了一个新的列表项元素序号1。
  3. 一旦鼠标移动处理器结束后,事件循环执行单击事件处理器,从而创建了另一个列表元素序号2,并附加在ID为second的第二个列表元素后。

小结

  1. 浏览器接收的HTML代码用作创建DOM的蓝图,它是客户端Web应
    用结构的内部展示阶段。

  2. 我们使用JavaScript代码来动态地修改DOM以便给Web应用带来动
    态行为。

  3. 客户端Web应用的执行分为两个阶段:

    ​ ==页面构建代码是用于创建DOM的,而全局JavaScript代码是遇到script节点时执行的。==在这个执行过程中,JavaScript代码能够以任意程度改变当前的DOM,还能够注册事件处理器——事件处理器是一种函数,当某个特定事件(例如,一次鼠标单击或键盘按压)发生后会被执行。注册事件处理器很容易:使用内置的addEventListener方法。

    ​ ==事件处理——在同一时刻,只能处理多个不同事件中的一个,处理顺序是事件生成的顺序。==事件处理阶段大量依赖事件队列,所有的事件都以其出现的顺序存储在事件队列中。事件循环会检查事件队列的队头,如果检测到了一个事件,那么相应的事件处理器就会被调用。

Guess you like

Origin www.cnblogs.com/King2019Blog/p/11299231.html