判断变量是否为数组类型

1
2
3
4
let arr  = [1,2,3];
function isArray (arr) {
return (typeof Array.isArray === 'function') ? Array.isArray(arr) : Object.prototype.toString.call(arr) === '[object Array]';
}

判断变量是否为字符串类型

1
2
3
4
5
6
7
let a = 'abc';//基本类型
let b = new String('ddd');//基本包装类型
let c = `ddd`;
//该函数能够检查基本数据类型的 String 和基本包装类型的 String
function isString(str) {
return (typeof str === 'string') || (Object.prototype.toString.call(str) === '[object String]');
}

从输入URL到页面加载发生了什么

  • 第一步:我们在浏览器地址栏输入域名如:facebook.com,并回车
  • 第二步:浏览器会查找域名对应的IP地址 (DNS解析
    • 网址(域名)到IP地址的转换,这个过程就是DNS解析
    • 浏览器缓存 - 浏览器缓存DNS记录一段时间。 有趣的是,操作系统并没有告诉浏览器每个DNS记录的生存时间,因此浏览器将它们缓存一段固定的时间(根据浏览器的不同而不同,2到30分钟)。
    • 操作系统缓存 - 如果浏览器缓存不包含所需的记录,浏览器会进行系统调用(Windows中为gethostbyname)。 操作系统有它自己的缓存。
    • 路由器高速缓存 - 请求继续到您的路由器,路由器通常有自己的DNS高速缓存。
    • ISP DNS缓存 - 检查的下一个地方是缓存ISP的DNS服务器。 自然,有了缓存。
    • 递归搜索 - 您的ISP的DNS服务器开始递归搜索,从根名称服务器,.com顶级域名服务器到Facebook的域名服务器。 通常,DNS服务器在高速缓存中将具有.com名称服务器的名称,因此命名根名称服务器不是必需的。
    • DNS存在着多级缓存,从离浏览器的距离排序的话,有以下几种: 浏览器缓存系统缓存路由器缓存IPS服务器缓存根域名服务器缓存顶级域名服务器缓存主域名服务器缓存
    • DNS负载均衡 DNS可以返回一个合适的机器的IP给用户,例如可以根据每台机器的负载量,该机器离用户地理位置的距离等等,这种过程就是DNS负载均衡,又叫做DNS重定向。大家耳熟能详的CDN(Content Delivery Network)就是利用DNS的重定向技术,DNS服务器会返回一个跟用户最接近的点的IP地址给用户。
  • 第三步:浏览器向Web服务器 发送HTTP请求

    • 这里是我请求facebook的信息,里面有很多的信息

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      :authority: www.facebook.com
      :method: GET
      :path: /
      :scheme: https
      accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
      accept-encoding: gzip, deflate, br
      accept-language: zh-CN,zh;q=0.9
      cache-control: no-cache
      cookie: sb=aTLYWlOXI_T1iqOU9VMMf9_x; fr=01DlbCAYk0IRgALsu..Baw4H5.oQ.AAA.0.0.Ba-BPH.AWXsKYJ_; _js_datr=xxP4WrQx0eDoGj9MEfCgsASE; _js_reg_fb_ref=https%3A%2F%2Fwww.facebook.com%2F; _js_reg_fb_gate=https%3A%2F%2Fwww.facebook.com%2F; wd=455x677
      pragma: no-cache
      upgrade-insecure-requests: 1
      user-agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36
    • 除GET请求之外,您可能熟悉的另一种类型的请求是POST请求,通常用于提交表单。 GET请求通过URL发送其参数, POST请求在请求正文中发送其参数。

  • 第四步:服务器以 永久性重定向 进行响应
  • 第五步:浏览器 遵循重定向
  • 第六步:服务器 处理请求
    • 服务器将收到GET请求,处理它。
    • Web服务器软件(例如IIS或Apache)接收HTTP请求并决定应执行哪个请求处理程序来处理此请求。 请求处理程序是一个程序(在ASP.NET,PHP,Ruby中),它读取请求并生成响应的HTML。
  • 第七步:服务器发回一个 HTML响应

    1
    2
    3
    4
    5
    Request URL: https://www.facebook.com/
    Request Method: GET
    Status Code: 200
    Remote Address: 127.0.0.1:1080
    Referrer Policy: no-referrer-when-downgrade
    • HTTP响应报文也是由三部分组成: 状态码, 响应报头和响应报文
    • 状态码是由3位数组成,第一个数字定义了响应的类别,且有五种可能取值:
    • 1xx:指示信息–表示请求已接收,继续处理。
    • 2xx:成功–表示请求已被成功接收、理解、接受。
    • 3xx:重定向–要完成请求必须进行更进一步的操作。
    • 4xx:客户端错误–请求有语法错误或请求无法实现。
    • 5xx:服务器端错误–服务器未能实现合法的请求。
    • 平时遇到比较常见的状态码有:200, 204, 301, 302, 304, 400, 401, 403, 404, 422, 500(分别表示什么请自行查找)。
  • 第八步:浏览器开始 呈现HTML
    • 即使在浏览器收到整个HTML文档之前,它也开始渲染网站
  • 第九步:浏览器发送 嵌入在HTML中的对象的请求
    • 当浏览器呈现HTML时,它会注意到需要获取其他URL的标签。 浏览器将发送一个GET请求来检索每个文件如:Images、css、js文件等
    • 这些URL中的每一个都会经历类似于HTML页面所经历的过程。 因此,浏览器将在DNS中查找域名,向URL发送请求,遵循重定向等。但是,静态文件 - 不像动态页面 - 允许浏览器缓存它们。 有些文件可能从缓存中提供,根本不需要联系服务器。 浏览器知道缓存特定文件需要多长时间,因为返回该文件的响应包含Expires标头。
    • 在这里的静态内容可以通过 内容分发网络(CDN)
  • 第十步:浏览器 发送进一步的异步(AJAX)请求

用 js 去除字符串空格

1
2
3
4
5
// str.replace(/\s*/g,'');//移除全部空格
// str.replace(/^\s*/g,'');//移除左边的空格
// str.replace(/\s*$/g,'');//移除右边的空格
// str.replace(/^\s*$/g,'');//移除左右的空格
// str.trim();//局限性:无法去除中间的空格

获取浏览器URL中的参数

1
2
3
4
5
6
let str = `http://www.baidu.com/jquery/misc-trim.html?channelid=12333&name=xiaoming&age=13`;
function queryPara (str) {
let result = {};
str.split('?')[1].split('&').forEach(item=>{result[item.split('=')[0]] = item.split('=')[1];});
return result;
}

求数组最值

1
2
3
let arr = [1,2,3,4,5,6,-3,-66,232];
console.log(Math.max.apply(null,arr));
console.log(Math.min.call(null,1,2,3,4,5,6,-3,-66,232));

js 中的变量作用域

  • 变量分类:全局变量局部变量
  • 作用域:全局作用域和函数的局部作用域
  • 函数内部可以读取函数外部的全局变量;在函数外部无法读取函数内的局部变量。
  • 函数内部声明变量的时候,一定要使用var命令。如果不用的话,你实际上声明了一个全局变量!

什么是跨域?方法有哪些?

  • 由于浏览器同源策略,凡是发送请求url的 协议域名端口三者之间任意一与当前页面地址不同即为跨域。
  • 跨域请求资源的方法
    • porxy代理
    • CORS [Cross-Origin Resource Sharing] 定义和用法:是现代浏览器支持跨域资源请求的一种最常用的方式。使用方法:一般需要后端人员在处理请求数据的时候,添加允许跨域的相关操作
    • jsonp 通过动态插入一个script标签。浏览器对script的资源引用没有同源限制,同时资源加载到页面后会立即执行
      • 一般情况,服务器端会返回一个 js 函数调用
      • 这种方式无法发送 post 请求
      • 另外要确定jsonp的请求是否失败并不容易,大多数框架的实现都是结合超时时间来判定
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        <script>
        function testjsonp(data) {
        console.log(data.name); // 获取返回的结果
        }
        </script>
        <script>
        var _script = document.createElement('script');
        _script.type = "text/javascript";
        _script.src = "http://localhost:8888/jsonp?callback=testjsonp";
        document.head.appendChild(_script);
        </script>

垃圾回收机制及内存管理

  • 定义和用法:垃圾回收机制(GC:Garbage Collection),执行环境负责管理代码执行过程中使用的内存
  • 原理:垃圾收集器会定期(周期性)找出那些不再继续使用的变量,然后释放其内存。但是这个过程不是实时的,因为其开销比较大,所以垃圾回收器会按照固定的时间间隔周期性的执行

    1
    2
    3
    4
    5
    6
    7
    8
    9
    function fn1() {
    var obj = {name: 'hanzichi', age: 10};
    }
    function fn2() {
    var obj = {name:'hanzichi', age: 10};
    return obj;
    }
    var a = fn1();
    var b = fn2();
  • fn1中定义的obj为局部变量,而当调用结束后,出了fn1的环境,那么该块内存会被js引擎中的垃圾回收器自动释放;在fn2被调用的过程中,返回的对象被全局变量b所指向,所以该块内存并不会被释放。

  • 垃圾回收策略:标记清除(较为常用) 和 引用计数
  • 标记清除:定义和用法:当变量进入环境时,将变量标记”进入环境”,当变量离开环境时,标记为:”离开环境”。某一个时刻,垃圾回收器会过滤掉环境中的变量,以及被环境变量引用的变量,剩下的就是被视为准备回收的变量。到目前为止,IE、Firefox、Opera、Chrome、Safari的js实现使用的都是标记清除的垃圾回收策略或类似的策略,只不过垃圾收集的时间间隔互不相同。
  • 引用计数:定义和用法:引用计数是跟踪记录每个值被引用的次数。基本原理:就是变量的引用次数,被引用一次则加1,当这个引用计数为0时,被视为准备回收的对象。这种方式存在 循环引用 的问题
  • 内存管理 垃圾回收器周期性运行,如果分配的内存非常多,那么回收工作也会很艰巨,确定垃圾回收时间间隔就变成了一个值得思考的问题。因此在写代码时 给不需要的内存手动赋值 null 有时是有必要的

开发过程中遇到的内存泄露情况,如何解决

  • 内存泄露 是指一块被分配的内存既不能使用,又不能回收,直到浏览器进程结束。C#和Java等语言采用了自动垃圾回收方法管理内存,几乎不会发生内存泄露。我们知道,浏览器中也是采用自动垃圾回收方法管理内存,但由于浏览器垃圾回收方法有bug,会产生内存泄露。
  • 内存泄露的一些情况(待补充)
    • 当页面中元素被移除或替换时,若元素绑定的事件仍没被移除,在IE中不会作出恰当处理,此时要先手工移除事件,不然会存在内存泄露。解决方法:当要移除或删除元素之前先手动清除事件如:obj.onclick = null;

js 创建对象的几种方式

js 面向对象中继承实现

字符串中每个字符出现的次数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//统计字符串中每个字符出现的次数
let str = 'abcdefgabcdefgaaaavbvb';
//该函数针对上述 str 返回一个对象 {a:6,b:4,c:2,d:2,e:2,f:2,g:2,v:2}
function count (str) {
//第一步:先找出有哪些字符出现过
let temp = [];//存放出现过的字符
let result = {};//结果对象
for (let i = 0; i < str.length; i++) {
if (temp.indexOf(str[i]) === -1) {
temp.push(str[i]);
}
}
//计算单个 固定字符 出现的次数
function countOne (s) {
let position = 0;
let num = 0;
while(position != -1) {
position = str.indexOf(s,position);
if (position != -1) {num++;position++}
}
return num;
}
temp.forEach(item=>{result[item] = countOne(item);});
return result;
}

数组去重

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//法一
function filterArr0 (arr) {
let result = [];
for (let i = 0; i < arr.length; i++) {
if (result.indexOf(arr[i]) === -1) {
result.push(arr[i]);
}
}
return result;
}
//法二:使用 数组的 filter方法
function filterArr1 (arr) {
return arr.filter((item,index,arr)=>arr.indexOf(item) === index);
}
//法三:使用 ES6 语法
function filterArr2 (arr) {
return Array.from(new Set(arr));
}
let a = [1,2,3,4,5,6,7,8,9,1,1,1,2,2,2,3,3,3,4,4,4,5,5,5,6,99];
console.log(filterArr0(a));//[1, 2, 3, 4, 5, 6, 7, 8, 9, 99]
console.log(filterArr1(a));//[1, 2, 3, 4, 5, 6, 7, 8, 9, 99]
console.log(filterArr2(a));//[1, 2, 3, 4, 5, 6, 7, 8, 9, 99]

盒子模型怎么理解

  • 这道题问得比较宽泛,一定要找准切入点,如果切入点找不准,很容易乱答,甚至答偏,所以找准切入点是非常的重要的。
  • 盒子模型有两种,W3CIE盒子模型
    • W3C定义的盒子模型包括margin、border、padding、content ,元素的width=content的宽度
    • IE盒子模型与W3C的盒子模型唯一区别就是元素的宽度,元素的width=content+padding+border
    • 个人认为W3C定义盒子模型与IE定义的盒子模型,IE定义的比较合理,元素的宽度应该包含border(边框)和padding(填充),这个和我们现实生活的盒子是一样的,W3C也认识到自己的问题了,所以在CSS3中新增了一个样式box-sizing,包含两个属性content-box 和 border-box。
    • box-sizing:content-box; :盒子在网页中实际占用的空间 = css设置的width + padding + border
    • box-sizing:border-box; :盒子在网页中实际占用的空间 = css设置的width = content + padding + border

行内元素?块级元素?

  • 常见块级元素:div、ul、li、dl、dt、dd、p、h1-h6、blockquote
  • 行内元素:a、b、span、img、input、strong、select、label、em、button、textarea
  • 对于行内元素,margin-top和margin-bottom对于上下元素无效,margin-left和margin-right有效
  • 对于相邻的块级元素margin-bottom和margin-top 取值方式
    • 都是正数: 取最大值
    • 都是负数: 取最小值

CSS实现垂直水平居中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
html结构
<div class="wrapper">
<div class="content"></div>
</div>
css
.wrapper {
position: relative;
width: 500px;
height: 500px;
border: 1px solid red;
}
.content{
position: absolute;
width: 200px;
height: 200px;
/*top、bottom、left和right 均设置为0*/
top: 0;
bottom: 0;
left: 0;
right: 0;
/*margin设置为auto*/
margin:auto;
border: 1px solid green;
}

简述 src 与 href 的区别

  • href 是指向网络资源所在位置,建立和当前元素(锚点)或当前文档(链接)之间的链接,用于超链接
  • src 是指向外部资源的位置,指向的内容将会嵌入到文档中当前标签所在位置;在请求src资源时会将其指向的资源下载并应用到文档内,例如js脚本,img图片和frame等元素。当浏览器解析到该元素时,会暂停其他资源的下载和处理,直到将该资源加载、编译、执行完毕,图片和框架等元素也如此,类似于将所指向资源嵌入当前标签内。这也是为什么将js脚本放在底部而不是头部
  • href 和 页面是同时加载的,而 script 标签 的 src 在不指定 async 或者 defer时会阻塞页面

简述同步和异步的区别

  • 同步是阻塞模式,异步是非阻塞模式
  • 同步就是指一个进程在执行某个请求的时候,若该请求需要一段时间才能返回信息,那么这个进程将会一直等待下去,直到收到返回信息才继续执行下去;
  • 异步是指进程不需要一直等下去,而是继续执行下面的操作,不管其他进程的状态。当有消息返回时系统会通知进程进行处理,这样可以提高执行的效率。

浏览器的内核分别是什么

  • Chrome :谷歌浏览器之前一直使用苹果的webkit内核,现在它与苹果内核分道扬镳,自己开创了新的 blink内核 (基于webkit,Google与Opera Software共同开发)
  • Opera :以前是presto内核,Opera现已改用Google Chrome的 Blink 内核
  • Safari :使用的是苹果公司自己的内核: webkit
  • Firefoxgecko内核
  • IE浏览器 是微软出品的浏览器,IE4以上版本都是 Trident内核

什么叫优雅降级和渐进增强

  • 渐进增强 progressive enhancement:
    • 针对低版本浏览器进行构建页面,保证最基本的功能,然后再针对高级浏览器进行效果、交互等改进和追加功能达到更好的用户体验。
  • 优雅降级 graceful degradation:
    • 一开始就构建完整的功能,然后再针对低版本浏览器进行兼容。
  • 区别:
    • a. 优雅降级是从复杂的现状开始,并试图减少用户体验的供给
    • b. 渐进增强则是从一个非常基础的,能够起作用的版本开始,并不断扩充,以适应未来环境的需要
    • c. 降级(功能衰减)意味着往回看;而渐进增强则意味着朝前看,同时保证其根基处于安全地带

sessionStorage 、localStorage 和 cookie 之间的区别

  • 共同点:用于 浏览器端存储的缓存数据
  • 不同点:
    • (1)、存储内容是否发送到服务器端:当设置了Cookie后,数据会发送到服务器端,造成一定的宽带浪费;web storage,会将数据保存到本地,不会造成宽带浪费
    • (2)、数据存储大小不同:Cookie数据不能超过4K,适用于会话标识;web storage数据存储可以达到5M
    • (3)、数据存储的有效期限不同:cookie只在设置了Cookid过期时间之前一直有效,即使关闭窗口或者浏览器
      sessionStorage,仅在关闭浏览器之前有效;localStorage,数据存储永久有效
    • (4)、作用域不同:cookie和localStorage是在同源同窗口中都是共享的;sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面

Web Storage 与 bCookie相比存在的优势

  • (1)、存储空间更大:IE8下每个独立的存储空间为10M,其他浏览器实现略有不同,但都比Cookie要大很多。
  • (2)、存储内容不会发送到服务器:当设置了Cookie后,Cookie的内容会随着请求一并发送的服务器,这对于本地存储的数据是一种带宽浪费。而Web Storage中的数据则仅仅是存在本地,不会与服务器发生任何交互。
  • (3)、更多丰富易用的接口:Web Storage提供了一套更为丰富的接口,如setItem,getItem,removeItem,clear等,使得数据操作更为简便。cookie需要自己封装。
  • (4)、独立的存储空间:每个域(包括子域)有独立的存储空间,各个存储空间是完全独立的,因此不会造成数据混乱。

Ajax的优缺点及工作原理

定义和用法:

AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。Ajax 是一种用于创建快速动态网页的技术。Ajax 是一种在 无需重新加载整个网页的情况下,能够更新部分网页 的技术。

传统的网页(不使用 Ajax)如果需要更新内容,必须重载整个网页页面。

  • 优点:

    • 1.减轻服务器的负担,按需取数据,最大程度的减少冗余请求
    • 2.局部刷新页面,减少用户心理和实际的等待时间,带来更好的用户体验
    • 3.被广泛支持,不需安装插件等,进一步促进页面和数据的分离
  • 缺点:

    • 1.AJAX大量的使用了javascript和ajax引擎,这些取决于浏览器的支持.在编写的时候考虑对 浏览器的兼容性
    • 2.AJAX只是局部刷新,所以页面的 后退按钮是没有用
    • 3.对流媒体还有移动设备的支持不是太好等
  • AJAX的工作原理

    • 1.创建ajax对象(XMLHttpRequest/ActiveXObject(Microsoft.XMLHttp))
    • 2.判断数据传输方式(GET/POST)
    • 3.打开链接 open()
    • 4.发送 send()
    • 5.当ajax对象完成第四步(onreadystatechange)数据接收完成,判断http响应状态(status)200-300之间或者304(缓存)执行回调函数

document load和document ready的区别

  • 共同点:这两种事件都代表的是页面文档加载时触发。
  • 异同点:
    • ready 事件的触发,表示文档结构已经加载完成(不包含图片等非文字媒体文件)
    • onload 事件的触发,表示页面 包含图片等文件在内的所有元素 都加载完成

请说出三种减低页面加载时间的方法

  • 压缩css、js文件
  • 合并js、css文件,减少http请求
  • 外部js、css文件放在最底下
  • 减少dom操作,尽可能用变量替代不必要的dom操作

前端开发,性能优化

  • 内容方面
    • 减少 HTTP 请求 (Make Fewer HTTP Requests)
    • 减少 DOM 元素数量 (Reduce the Number of DOM Elements)及操作 DOM 的频率
  • 针对CSS
    • 把 CSS 放到代码页上端 (Put Stylesheets at the Top)
    • 从页面中剥离 JavaScript 与 CSS (Make JavaScript and CSS External)
    • 精简 JavaScript 与 CSS (Minify JavaScript and CSS)
    • 避免 CSS 表达式 (Avoid CSS Expressions)
  • 针对JavaScript
    • 脚本放到 HTML 代码页底部 (Put Scripts at the Bottom)
    • 从页面中剥离 JavaScript 与 CSS (Make JavaScript and CSS External)
    • 精简 JavaScript 与 CSS (Minify JavaScript and CSS)
    • 移除重复脚本 (Remove Duplicate Scripts)
  • 面向图片(Image)
    • 优化图片
    • 不要在 HTML 中使用缩放图片
    • 使用恰当的图片格式
    • 使用 CSS Sprites 技巧对图片优化,加速的关键,不是降低质量,而 减少个数。传统切图讲究精细,图片规格越小越好,重量越小越好,其实规格大小无所谓,计算机统一都按byte计算。客户端每显示一张图片都会向服务器发送请求。所以,图片越多请求次数越多,造成延迟的可能性也就越大。CSS Sprites其实就是把网页中一些背景图片整合到一张图片文件中,再利用CSS的“background-image”,“background- repeat”,“background-position”的组合进行背景定位,background-position可以用数字精确的定位出背景图片的位置

如何优化图像?图像格式的区别?

  • 优化图像
    • 不用图片,尽量 用css3 代替。 比如说要实现修饰效果,如半透明、边框、圆角、阴影、渐变等,在当前主流浏览器中都可以用CSS达成
    • 使用 矢量图SVG 替代位图。对于绝大多数图案、图标等,矢量图更小,且可缩放而无需生成多套图。现在主流浏览器都支持SVG了,所以可放心使用
    • 使用 恰当的图片格式 我们常见的图片格式有JPEG、GIF、PNG。基本上,内容图片多为照片之类的,适用于JPEG。而修饰图片通常更适合用无损压缩的PNG。GIF基本上除了GIF动画外不要使用。且动画的话,也更建议用video元素和视频格式,或用SVG动画取代
    • 使用字体图标webfont、CSS Sprites等
    • 用CSS或JavaScript实现预加载
    • WebP图片格式能给前端带来的优化。WebP支持无损、有损压缩,动态、静态图片,压缩比率优于GIF、JPEG、JPEG2000、PG等格式,非常适合用于网络等图片传输
  • 图像格式的区别
    • 矢量图:图标字体,如 font-awesome;svg
    • 位图:gif,jpg(jpeg),png
    • 1、gif:是是一种无损,8位图片格式。具有支持动画,索引透明,压缩等特性。适用于做色彩简单(色调少)的图片,如logo,各种小图标icons等。
    • 2、JPEG格式是一种大小与质量相平衡的压缩图片格式。适用于允许轻微失真的色彩丰富的照片,不适合做色彩简单(色调少)的图片,如logo,各种小图标icons等。
    • 3、png:PNG可以细分为三种格式:PNG8,PNG24,PNG32。后面的数字代表这种PNG格式最多可以索引和存储的颜色值。关于透明:PNG8支持索引透明和alpha透明;PNG24不支持透明;而PNG32在24位的PNG基础上增加了8位(256阶)的alpha通道透明;
  • 优缺点:
      + 1、能在保证最不失真的情况下尽可能压缩图像文件的大小
      + 2、对于需要高保真的较复杂的图像,PNG虽然能无损压缩,但图片文件较大,不适合应用在Web页面上

浏览器是如何渲染页面

  • 1.解析HTML文件,创建DOM树。
    • 自上而下,遇到任何样式(link、style)与脚本(script)都会阻塞(外部样式不阻塞后续外部脚本的加载)。
  • 2.解析CSS。优先级:浏览器默认设置<用户设置<外部样式<内联样式<HTML中的style样式;
  • 3.将CSS与DOM合并,构建渲染树(Render Tree)
  • 4.布局和绘制,重绘(repaint)和重排(reflow)