[TOC]

JavaScript 语言最初是为 Web 浏览器创建的。此后,它已经演变成了一种具有多种用途和平台的语言。
平台可以是一个浏览器,一个 Web 服务器,或其他 主机(host),甚至可以是一个“智能”咖啡机,如果它能运行 JavaScript 的话。它们每个都提供了特定于平台的功能。JavaScript 规范将其称为 主机环境
当然我们目前关注的是WEB开发下的JS。

image.png

文档对象模型(DOM)

文档对象模型 (DOM) 将 web 页面与到脚本或编程语言连接起来,文档对象模型 (DOM) 将 web 页面与到脚本或编程语言连接起来。
根据文档对象模型(DOM),每个 HTML 标签都是一个对象。嵌套的标签是闭合标签的“子标签(children)”。标签内的文本也是一个对象。
所有这些对象都可以通过 JavaScript 来访问,我们可以使用它们来修改页面。
例如,我们可以操作Dom实现一些操作,去简单的修改页面

document.body.style.background = 'red'; // 将背景设置为红色

setTimeout(() => document.body.style.background = '', 3000); // 恢复回去

在这,我们使用了 style.background 来修改 document.body 的背景颜色,但是body还有很多其他的属性,在合适的情况下你都可以对其修改。

获取DOM

既然DOM 让我们可以对元素和它们中的内容做任何事,但是首先我们需要获取到对应的 DOM 对象。
最顶层的树节点可以直接作为 document 的属性来使用:
= document.documentElement
最顶层的 document 节点是 document.documentElement。这是对应 标签的 DOM 节点。
= document.body
另一个被广泛使用的 DOM 节点是 元素 —— document.body。
= document.head
标签可以通过 document.head 访问。

举个例子,你可以试着在你喜欢的网页上,打开控制台,复制运行下面的代码

let a =document.getElementsByTagName('div')

for(item of a){
    console.log(item)
}

这里获取到了页面中所有的div元素,用for of(迭代器的语法糖)遍历输出了这个a这个‘数组’,这样你就可以看到页面里的div元素一个个打印。

获取DOM元素的方式

获取DOM元素的基本方式就是通过选择器获取

Document.getElementsById()

通过ID选择器选择到对应的DOM元素

Document.getElementsByClassName(‘area’)

class=’area’
通过类名选择器选择到对应的DOM元素

Document.getElementsByTagName(‘p’)

通过标签选择器选择到对应的DOM元素

document.querySelector()

image.png
最推荐:因为简单,好记
document.querySelector(‘.container’);//获取类名盒子
document.querySelector(‘#title’)获取ID盒子
注意,如果有不止一个元素,那么默认选择第一个节点

创建DOM

Document.createElement()

通过这个API你可以动态的创建一个p元素,并把它添加到你希望添加到的区域去渲染

const child=document.createElement('p')

child.append('hello world')

const container = document.querySelector('#container')

container.append(child)

修改DOM

讲修改DOM之前,我们先学习怎么添加事件,即在触发某个事件的时候再去对DOM元素作出对应的修改
image.png
请注意,事件绝不只有表里列出的这些,感兴趣可以去 查阅类似鼠标事件,键盘事件等等。
形胜于言,接下来打开课前准备的文件吧

浏览器相关知识

浏览器主要由以下几个部分组成:

  1. 用户界面
  2. 浏览器引擎
  3. 渲染引擎
  4. 数据存储层
  5. UI BackEnd
  6. JavaScript 解析器 (脚本引擎)
  7. 网络层

用户界面

这是用户与浏览器发生交互的区域。浏览器的外观没有特定的标准,HTML5 规范没有规定 UI 元素该长什么样,但是列了一些常见元素:地址栏、个人信息栏、滚动条、状态栏和工具栏等。

浏览器引擎

它提供了 UI 与底层渲染引擎之间的接口,根据用户交互进行查询和操控渲染引擎,提供初始化加载 URL 的方法,并负责重新加载、返回和前进等操作。

渲染引擎

渲染引擎负责在屏幕上显示网页内容。渲染引擎的主要工作是解析 HTML。渲染引擎默认可展示 HTML、XML和图片,还可以通过插件或扩展程序支持其他数据类型。
image.png
web 内容渲染过程大致如下:

HTML 数据转成 DOM

来自网络层的请求内容在渲染引擎中接收(通常是 8 kb 的块),然后将原始字节转换为 HTML 文件中的字符(基于字符编码)。接着词法分析器进行词法分析,将输入分解为各种标记(token)。在标记化过程中,文件中的每个开始和结束标签都被记录下来。它知道如何去掉不相关的字符,比如空格和换行符。
接着,解析器进行语法分析,通过分析文档结构,应用语言语法规则构造解析树。解析过程是迭代进行的。它向词法分析器请求新的 token,如果匹配语法规则,token 就被添加到解析树中。然后再请求另一个 token。如果没有匹配的规则,解析器将在内部存储 token,并不断请求新 token,直到找到匹配所有内部存储 token 的规则。如果没有找到规则,解析器将抛出异常,说明文档无效,包含语法错误。
这些节点在 DOM(文档对象模型)树数据结构中互相链接,建立父子关系、相邻兄弟关系。

联合授课第六次授课--JavaScript与浏览器原理 - 图5

dom-tree

CSS 数据转成 CSSOM

CSS 数据原始字节被转换成字符、token、节点,最终变成 CSSOM(CSS 对象模型)。CSS 的层级特性决定了元素会应用什么样式。元素的样式数据可以来自父元素(通过继承),也可以直接在元素上设置。浏览器需要递归遍历 CSS 树结构来确定特定元素的样式。

联合授课第六次授课--JavaScript与浏览器原理 - 图6
cssom-tree

DOM 与 CSSOM 组成渲染树

DOM 树包含了 HTML 元素之间的关系信息,CSSOM 树则包含了这些元素的样式信息。从根节点开始,浏览器会遍历每一个可见节点。有些节点是隐藏的(通过 CSS 控制),不会出现在渲染结果中。对于每个可见节点,浏览器找到 CSSOM 中定义的相关规则进行匹配,最终这些节点会带着内容和样式出现在渲染树中。

联合授课第六次授课--JavaScript与浏览器原理 - 图7

render-tree

布局

接下来进行内容布局。内容的实际尺寸和位置需要经过计算才能渲染到页面上(浏览器视口)。这个过程也叫重排(reflow)。HTML 采用基于流的布局模型,也就是说大部分情况下,几何位置是一次性计算出来的(内容大小或位置发生变化,需要重新计算)。这个过程是从文档根元素开始,递归完成的。

绘制

通过遍历每个渲染器,并调用paint方法在屏幕上显示内容。绘制过程可以是全局的(绘制整个树),也可以是增量的(渲染树在屏幕上验证某个矩形区域),操作系统在这些特定节点上生成绘制事件,整个树不受影响。绘制是一个渐进的过程,其中一部分在被解析和渲染过后,而该过程将继续处理其余部分

JavaScript 解析器 (JS 引擎)

JavaScript 是一种脚本语言,可动态更新 Web 内容、控制多媒体和动画等,这些是通过浏览器的 JS 引擎完成的。DOM 和 CSSOM 提供了 JS 接口,都可以通过 JS 修改。由于浏览器不确定某些 JS 会做什么,因此它会在遇到 script 标签后会立即暂停构建 DOM 树。
JS 解析器在接收到服务器发送来的代码后,会立即进行解析。代码被转换成机器能理解的对象表示形式。保存了所有解析信息的对象叫做抽象语法树(AST),这些对象又被解析器转换成字节码。这种编译方式叫做Just In Time (JITs) ,也就是 JavaScript 从服务器下载后在客户端实时编译。解析器和编译器是组合使用的,解析器立即处理源代码,编译器则生成机器码,客户端操作系统可直接运行。

UI 后台

用于绘制基础控件,比如复选框和窗口等。底层使用操作系统的用户界面方法,暴露通用的接口,跟平台无关。

数据存储层

这是持久化层,辅助浏览器保存一些数据(比如cookies,session storage,indexed DB,Web SQL,书签,用户偏好设置等)。HTML5 规范提出了浏览器端的完整数据库功能。

什么是Web存储


Web Storage也是一种在客户端存储数据的一种机制,主要的目的是为了克服由cookie带来的一些限制,当数据需要被严格控制在客户端上时,无须将数据在客户端和服务器之间来回的进行传送,并且可以存储大量的跨会话的数据

1、localStorage

(1)什么是localStorage
localStorage对象在修订过的html5规范中作为持久保存客户端数据的方案却带了globalStorage,与globalStorage不同,不能给localStorage指定任何访问规则,因为规则已经事先订好了,要访问同一个localStorage对象,页面必须来自同一个域名,使用同一种协议,在同一个端口
(2)如何使用localStorage存储数据
由于localStorage是Storage的实例,可以像使用sessionStorage一样来使用它
localStorage.setItem(“ifClick”,”true”);
当我们要获取数据的时候,可以像下面这样获取
localStorage.getItem(“ifClick”);
存储在localStorage中的数据和存储在globalStorage中的数据一样,都遵循相同的规则,数据保留到通过js删除或者是用户清除浏览器缓存
(3)localStorage的特点
a、localStorage会可以将第一次请求的数据直接存储到本地,这个相当于一个5M大小的针对于前端页面的数据库,相比于cookie可以节约带宽,但是这个却是只有在高版本的浏览器中才支持的
b、目前所有的浏览器中都会把localStorage的值类型限定为string类型,这个在对我们日常比较常见的JSON对象类型需要一些转换
c、localStorage本质上是对字符串的读取,如果存储内容多的话会消耗内存空间,会导致页面变卡
最后,要和大家说的是,sessionStorage和localStorage都克服了cookie的一些限制,它们都有很多共同的特点,localStorage与sessionStorage的唯一一点区别就是localStorage属于永久性存储,而sessionStorage属于当会话结束的时候,sessionStorage中的键值对会被清空

2、sessionStorage
(1)什么是sessionStorage
sessionStorage对象是存储特定于某个会话的数据,也就是数据只保存到浏览器关闭,这个对象就像会话cookie,也会在浏览器关闭后消失,存储在sessionStorage中的数据可以跨越页面刷新而存在
(2)如何使用sessionStorage存储数据
由于sessionStorage对象是Storage的一个实例,所以存储数据时可以使用setItem()或者直接设置新的属性来存储数据
// 使用方法存储数据 sessionStorage.setItem(“ifClick”, “true”); // 使用属性存储数据 sessionStorage.ifClick = “true”;
当我们要获取某个数据的时候,可以使用getItem来获取数据
sessionStorage.getItem(“ifClick”);
我们现在又成功获取到ifClick的值啦,当然也可以通过length属性和key()方法来获取sessionStorage的值
(3)sessionStorage的特点
a、同源策略限制,若想在不同页面之间对同一个sessionStorage进行操作,这些页面必须在同一协议、同一主机名和同一端口下
b、单标签页限制,sessionStorage操作限制在单个标签页中,在此标签页进行同源页面访问都可以共享sessionStorage数据
c、只在本地存储,seesionStorage的数据不会跟随HTTP请求一起发送到服务器,只会在本地生效,并在关闭标签页后清除数据
d、存储方式,seesionStorage的存储方式采用key、value的方式
e、存储上限限制:不同的浏览器存储的上限也不一样,但大多数浏览器把上限限制在5MB以下

网络层

在网络层面,对于前端开发者,必须要知道浏览器拥有的两大核心能力:

  • 自动发出请求的能力
  • 自动解析响应的能力

    自动发出请求的能力

    当一些事情发生的时候,浏览器会代替用户自动发出http请求,常见的包括:
  1. 用户在地址栏输入了一个url地址,并按下了回车浏览器会自动解析URL,并发出一个GET请求,同时抛弃当前页面。
  2. 当用户点击了页面中的a元素浏览器会拿到a元素的href地址,并发出一个GET请求,同时抛弃当前页面。
  3. 当用户点击了提交按钮浏览器会获取按钮所在的
    元素,拿到它的action属性地址,同时拿到它method属性值,然后把表单中的数据组织到请求体中,发出指定方法的请求,同时抛弃当前页面。这种方式的提交现在越来越少见了
  4. 当解析HTML时遇到了 联合授课第六次授课--JavaScript与浏览器原理 - 图8