运行时的页面构建过程

前言

本文是阅读《JavaScipt忍者秘籍》的心得体会css

  • 浏览器是否会老是根据给定的html来渲染页面?
  • web 应用一次能处理多少个事件?
  • 为何浏览器使用事件队列来处理事件?

1、web应用的生命周期

典型的生命周期当用户输入url,浏览器向服务器发送了请求服务器接收了请求而且返回一个由html,css,hmtl组成的响应浏览器接收了该响应后就开始了。html

而后浏览器开始根据响应构建页面建立用户界面。而后开始作事件处理,进入事件队列的循环中,等待事件的发生,而后调用处理器。web

应用的生命周期随这用户关掉或者离开界面结束api

2、如何构建页面?

  • 解析HTML代码并构建文档对象模型(DOM)
  • 执行JavaScript代码

在页面构建过程当中这两个步骤会交替执行屡次。浏览器

#HTML解析和DOM构建

浏览器经过解析接收到的HTML代码构建一个个HTML元素来构建DOM。bash

在这个过程当中每个HTML元素都被当成一个节点,除了根节点外每个节点都只有一个父节点,能够有任意数量个子节点,同一个元素节点的子节点被称做兄弟节点。服务器

以HTML为蓝本渲染DOM的时候还会自动修复一些错误。app

<html>
    <head>
        <div></div>
    </head>
    <body>
    <body>
</html>
复制代码

在这里咱们把内容元素div放到了header中。 dom

image

浏览器自动把它调整到了body中异步

直到咱们遇到了一种特殊类型的HTML元素——脚本元素,脚本元素中包括JavaScript代码,当我们遇到了这种元素就必须中止DOM的渲染开始执行JavaScript代码。

#执行JavaScript代码

js代码由浏览器引擎执行,firefox的Spidemonkey引擎,Chrome和Opera 和V8引擎和IE的Chakra引擎。js代码的目的是提供动态页面,浏览器经过全局对象提供了api使JavaScript引擎能够与之交互并改变其内容。

#JavaScript中的全局对象

JavaScript对象中存在一个window对象,它表明了整个包含页面的窗口。

它最重要的属性是document,表明了当前页面的dom。

window对象是老大,经过跟老大接触咱们能够获取其余全部的全局对象,全局变量和浏览器API的访问途径。咱们能够在任何程度上改变DOM,修改,删除,添加节点。

#全局代码和函数代码

位置上函数外的是全局变量,函数内的函数变量。

执行方式上去全局代码会由JavaScript引擎以一种直接的方式自动执行,要想执行函数代码就要被其余代码调用,能够是全局代码,也能够是其余函数,又或者是被浏览器调用。

在页面构建阶段,若是遇到了脚本节点,浏览器就会中止从HTML到DOM的节点,开始执行JavaScript代码。看以下代码

<body>
    
    <button id="button1" type="button"></button>
    <!--建立一个函数,点击添加元素,给元素添加内容插入到dom节点。-->
    <script>
        function createButton(element, content) {
            var createMessage = window.document.createElement('div');
            createMessage.textContent = content;
            element.appendChild(createMessage);

        }
        var button1 = document.getElementById('button1');
        createButton(button1, '哈哈哈哈')
    </script>
    
    <div id="div1"></div>
    <!--建立一个点击事件,调用以前建立的函数-->
    <script>
        window.document.body.onclick = function () {
            var div1 = document.getElementById('div1')
            createButton(div1, '笑一个吧~')
        }
    </script>
</body>
复制代码

JavaScript几乎能够添加删除修改全部的节点,可是它不能去动没有建立的节点,因此为了不这个问题,咱们要把JavaScript代码放到页面底部。

当JavaScript代码执行结束后,浏览器就退出了JavaScript的执行模式继续HTML到DOM的解析过程直到再次遇到脚本节点。重复以上过程。最后页面建立阶段就结束了。

而且在这个过程当中全部建立的全局变量都能正常被其余脚本元素中的JavaScript代码访问到。缘由在于全局对象window对象在整个页面的生存期当中。

3、事件处理

事件处理的重点在于一次只能执行一个代码片断,能够想象一下食堂一次只能一我的打饭。

因为一次只能执行一个代码片断,浏览器把触发的事件依次推到了一个事件队列中以这种方式来跟踪还没有处理的事件。

浏览器会检查事件队列头,若是没有找到就继续检查,若是找到了事件就取出该事件执行相应的事件处理器,重复执行。

此外放置事件的队列是独立在页面构建阶段和事件处理阶段之外的。

#异步

事件是异步的,代码的提早创建是为了保证以后的执行。

#注册事件处理器

  • 一个方法是把函数赋给某些特殊属性
window.onload=function(){}
复制代码
  • 使用内置方法 addEventListener
document.body.addEventListener("onclick",function(){})
复制代码

使用后者的优点在于能够注册尽量多的事件,而前者只能注册一个事件处理器

#处理事件的流程

触发事件后,事件被推到事件队列中。

image

解决问题

  • 浏览器是否会老是根据给定的html来渲染页面?

是的。可是不只仅是THML,在页面构建过程当中解析HTML成DOM和JavaScript代码的执行是交替进行的(这里不讲css)

  • web 应用一次能处理多少个事件?

一次一个。因为JavaScipt基于一个单线程的执行模型。

  • 为何浏览器使用事件队列来处理事件?

由于一次只能执行一个,因此为了追踪触发的事件就使用了事件队列,而且队列是先进先出的页很公平。

相关文章
相关标签/搜索