Skip to content

笔记 #1

@L1StayHungry

Description

@L1StayHungry

@TOC

前端基础

HTTP/HTTPS

http和https的基本概念

http: 超文本传输协议,是一个客户端和服务端请求和应答的标准,用于从WWW服务器传输超文本到本地浏览器的传输协议,它可以使浏览器更加高效,使网络传输减少。传输的数据没有经过加密(明文)

https: 是http的安全版,即http下加入ssl层,https的安全基础是ssl,因此加密的详细内容需要ssl

http和https的区别

1.https协议需要cat证书,费用较高

2.http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议

3.使用的端口不同。一般而言,http协议的端口为80,https的端口为443

4.http的连接很简单,是无状态的;https协议是由ssl+http协议构建的可进行加密传输、身份认证的网络协议,比http协议安全

https工作原理

1.客户端使用https url访问服务器,请求web服务器建立ssl链接

2.web服务器接收到客户端的请求之后,会将网站的证书(含公钥),返回、传输给客户端

3.客户端和web服务器端开始协商SSL链接的安全等级(加密等级)

4.客户端通过协商好的安全等级,建立会话密钥,然后通过网站的公钥来加密会话密钥,并传送给网站(服务端)

5.web服务器通过自己的私钥解密出会话密钥

6.web服务器通过会话密钥加密与客户端之间的通信

https优点

  • 使用https协议可以认证用户和服务器,确保数据发送到正确的客户机和服务器
  • https协议是由ssl+http协议构建的可进行加密传输、身份认证的网络协议,要比http协议安全,可防止数据在传输过程中不被窃取、改变,确保数据的完整性
  • https是现行架构下最安全的解决方案,虽然不是绝对安全,但它大幅增加了中间人攻击的成本

https缺点

  • https握手阶段比较费时,会使页面加载时间延长50%,增加10%~20%耗电
  • https缓存不如http高效,会增加数据开销
  • ssl证书要钱,功能越强大的证书费用越高
  • ssl证书需要绑定ip,不能在同一个ip上绑定多个域名,ipv4资源支持不了这种消耗

状态码

分类 分类描述
1** 信息,服务器收到请求,需要请求者继续执行操作
2** 成功,操作被成功接收并处理
3** 重定向,需要进一步的操作以完成请求
4** 客户端错误,请求包含语法错误或无法完成请求
5** 服务器错误,服务器在处理请求的过程中发生了错误
状态码 状态码英文名称 中文描述
100 Continue 继续。客户端应继续其请求
101 Switching Protocols 切换协议。服务器根据客户端的请求切换协议。只能切换到更高级的协议,例如,切换到HTTP的新版本协议
200 OK 请求成功。一般用于GET与POST请求
201 Created 已创建。成功请求并创建了新的资源
202 Accepted 已接受。已经接受请求,但未处理完成
203 Non-Authoritative Information 非授权信息。请求成功。但返回的meta信息不在原始的服务器,而是一个副本
204 No Content 无内容。服务器成功处理,但未返回内容。在未更新网页的情况下,可确保浏览器继续显示当前文档
205 Reset Content 重置内容。服务器处理成功,用户终端(例如:浏览器)应重置文档视图。可通过此返回码清除浏览器的表单域
206 Partial Content 部分内容。服务器成功处理了部分GET请求
300 Multiple Choices 多种选择。请求的资源可包括多个位置,相应可返回一个资源特征与地址的列表用于用户终端(例如:浏览器)选择
301 Moved Permanently 永久移动。请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替
302 Found 临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URI
303 See Other 查看其它地址。与301类似。使用GET和POST请求查看
304 Not Modified 未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源
305 Use Proxy 使用代理。所请求的资源必须通过代理访问
306 Unused 已经被废弃的HTTP状态码
307 Temporary Redirect 临时重定向。与302类似。使用GET请求重定向
400 Bad Request 客户端请求的语法错误,服务器无法理解
401 Unauthorized 请求要求用户的身份认证
402 Payment Required 保留,将来使用
403 Forbidden 服务器理解请求客户端的请求,但是拒绝执行此请求
404 Not Found 服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置"您所请求的资源无法找到"的个性页面
405 Method Not Allowed 客户端请求中的方法被禁止
406 Not Acceptable 服务器无法根据客户端请求的内容特性完成请求
407 Proxy Authentication Required 请求要求代理的身份认证,与401类似,但请求者应当使用代理进行授权
408 Request Time-out 服务器等待客户端发送的请求时间过长,超时
409 Conflict 服务器完成客户端的 PUT 请求时可能返回此代码,服务器处理请求时发生了冲突
410 Gone 客户端请求的资源已经不存在。410不同于404,如果资源以前有现在被永久删除了可使用410代码,网站设计人员可通过301代码指定资源的新位置
411 Length Required 服务器无法处理客户端发送的不带Content-Length的请求信息
412 Precondition Failed 客户端请求信息的先决条件错误
413 Request Entity Too Large 由于请求的实体过大,服务器无法处理,因此拒绝请求。为防止客户端的连续请求,服务器可能会关闭连接。如果只是服务器暂时无法处理,则会包含一个Retry-After的响应信息
414 Request-URI Too Large 请求的URI过长(URI通常为网址),服务器无法处理
415 Unsupported Media Type 服务器无法处理请求附带的媒体格式
416 Requested range not satisfiable 客户端请求的范围无效
417 Expectation Failed 服务器无法满足Expect的请求头信息
500 Internal Server Error 服务器内部错误,无法完成请求
501 Not Implemented 服务器不支持请求的功能,无法完成请求
502 Bad Gateway 作为网关或者代理工作的服务器尝试执行请求时,从远程服务器接收到了一个无效的响应
503 Service Unavailable 由于超载或系统维护,服务器暂时的无法处理客户端的请求。延时的长度可包含在服务器的Retry-After头信息中
504 Gateway Time-out 充当网关或代理的服务器,未及时从远端服务器获取请求
505 HTTP Version not supported 服务器不支持请求的HTTP协议的版本,无法完成处理

TCP三次握手

  • Client发起连接请求(seq=x)
  • Server接收到C的请求,并且同样发送连接请求(seq=y)和返回客户端请求的同意连接(ask = x+1)
  • 客户端接收服务端的连接请求,并且返回服务端请求的同意连接(ask = y+1)。

TCP和UDP的区别

  • TCP是面向连接的,UDP是无连接的
  • TCP提供可靠服务、数据按序到达;UDP不可靠传输、尽最大努力交付
  • TCP面向字节流,UDP面向报文、并且网络出现拥挤不会使发送速率降低(因此会出现丢包)
  • TCP只能1对1,UDP支持1对多
  • TCP首部较大,为20字节;UDP只有8个字节

从输入URL到渲染

  • 寻找缓存是否存在记录(IP地址、端口号)
  • (若无缓存)DNS查询IP地址。
  • TCP三次握手。应用层会下发数据给传输层,这里 TCP 协议会指明两端的端口号,然后下发给网络层。网络层中的 IP 协议会确定 IP 地址,并且指示了数据传输中如何跳转路由器。然后包会再被封装到数据链路层的数据帧结构中,最后就是物理层面的传输了
  • TCP 握手结束后会进行 TLS 握手,然后就开始正式的传输数据
  • 数据在进入服务端之前,可能还会先经过负责负载均衡的服务器,它的作用就是将请求合理的分发到多台服务器上,这时假设服务端会响应一个 HTML 文件
  • 首先浏览器会判断状态码是什么,如果是 200 那就继续解析,如果 400 或 500 的话就会报错,如果 300 的话会进行重定向,这里会有个重定向计数器,避免过多次的重定向,超过次数也会报错
  • 浏览器开始解析文件,如果是 gzip 格式的话会先解压一下,然后通过文件的编码格式知道该如何去解码文件
  • 文件解码成功后会正式开始渲染流程,先会根据 HTML 构建 DOM 树,有 CSS 的话会去构建 CSSOM 树。如果遇到 script 标签的话,会判断是否存在 async 或者 defer ,前者会并行进行下载并执行 JS,后者会先下载文件,然后等待 HTML 解析完成后顺序执行,如果以上都没有,就会阻塞住渲染流程直到 JS 执行完毕。遇到文件下载的会去下载文件,这里如果使用 HTTP 2.0 协议的话会极大的提高多图的下载效率。
  • 初始的 HTML 被完全加载和解析后会触发 DOMContentLoaded 事件
  • CSSOM 树和 DOM 树构建完成后会开始生成 Render 树,这一步就是确定页面元素的布局、样式等等诸多方面的东西。在生成 Render 树的过程中,浏览器就开始调用 GPU 绘制,合成图层,将内容显示在屏幕上

什么是webSocket,webSocket有什么优点

  • webSocket是HTML5中的协议,支持持久连接,http协议不支持持久性连接。Http1.0

    和Http1.1都不支持持久性连接,Http1.1中的keep-alive,将多个http请求合并为1个

  • Http的生命周期通过Request来界定,也就是Request一个Response,那么在Http1.0协议中,这次http请求就结束了。在Http1.1中,有一个connection: Keep-alive,也就是说,在一个Http连接中,可以发送多个Request,接收多个Reponse。但是必须记住,在http中一个Request只能对应一个Response,而且这个response是被动的,不能主动发起。

  • Webscoket是基于Http协议的,或者说是借用了http协议来完成一部分握手,在握手阶段与http是相同的。

说一下http2.0

http2.0是基于1999年发布的http1.0之后的首次更新

  • 提升访问速度。相对http1.0,请求资源所需时间更少,访问速度更快,相比http1.0
  • 允许多路复用:多路复用允许同时通过单一的HTTP/2连接发送多重请求-响应信息。改善了:http1.1中,浏览器客户端在同一时间,针对同一域名下的请求有一定数量限制,超过限制会被阻塞。
  • 二进制分帧:将所有传输的信息分割为更小的信息或者帧,并对他们进行二进制编码首部压缩
  • 服务器端推送

fetch发送两次请求的原因

fetch发送请求的时候总是发送两次,第一次状态码是204,第二次才成功。

原因是,用fetch的post请求时,导致fetch第一次发送了一个options请求,询问服务器是否支持修改的请求头,若支持,则在第二次发送真正的请求。

HTML/浏览器

浏览器渲染机制

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tea4fUDu-1602918160157)(C:\Users\16643\AppData\Roaming\Typora\typora-user-images\image-20201015150117194.png)]

浏览器缓存策略

浏览器缓存机制有四个方面,它们按照获取资源时请求的优先级依次排列如下:

  • Memory Cache:内存中的缓存
  • Service Worker Cache:独立于主线程之外的js线程
  • HTTP Cache:分为强缓存和协商缓存
  • Push Cache:指 HTTP2 在 server push 阶段存在的缓存

有哪些常用的Bom属性?

(Bom:浏览器对象)

  1. location对象
    • location.href :返回或设置当前文档的URL
    • location.search :返回URL中的查询字符串部分。包括(?)以及其后面字符
    • location.hash :返回URL#后面的内容。若没有#,返回空
    • location.host :返回URL中的域名部分。www.xxxxxx.com
    • location.hostname :返回URL中的主域名部分。xxxxxx.com
    • location.pathname :返回域名后的部分
    • location.port :返回url中的端口部分
    • location.protocol :返回url中的协议部分。http:
    • location.assign :设置当前文档的url
    • location.replace() :设置当前文档的url,并且在history对象的地址列表中移除这个url
    • location.reload() :重载当前页面
  2. history对象
    • history.go :前进或后退指定页数
    • history.back() :后退一页
    • history.forword() :前进一页
  3. Navigator对象
    • navigator.userAgent :返回用户代理头的字符串表示(包括浏览器版本信息等的字符串)
    • navigator.cookieEnabled :返回浏览器是否支持(启用)cookie

说一下HTML5 drag api

  • dragstart: 事件主体是被拖放元素,在开始拖放被拖放元素时触发
  • drag: 事件主体是被拖放元素,在正在拖放被拖放元素时触发
  • dragenter: 事件主体是目标元素,在被拖放元素进入某元素时触发
  • dragover: 事件主体是目标元素,在被拖放元素内移动时触发
  • dragleave: 事件主体是目标元素,在被拖放元素移出目标元素时触发
  • drop: 事件主体是目标元素,在目标元素完全接受被拖放元素时触发
  • dragend: 事件主体是被拖放元素,在整个拖放操作结束时触发

H5新属性

  • 语义化标签:header、section、footer、aside、nav、main、article、figure
  • 内容元素:mark高亮 progress进度
  • canvas绘图,支持内联SVG,支持MathML
  • 多媒体audio、video、source、embed、track
  • web存储。localStorage,SessionStorage

状态码

  • 400:请求无效:前端提交的数据类型与后台不一致。
  • 401:当前请求需要用户验证
  • 403:服务器已经得到请求,但拒绝执行

Cookie sessionStorage localStorage的区别

  • cookie:cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递。而sessionStorage和LocalStorage不会自动把数据发给服务器,仅在本地保存。cookie数据还有路径的概念,可以限制cookie只属于某个路径下,存储的大小很小,只有4k左右。
  • sessionStorage: 仅在当前浏览器窗口关闭前有效
  • localStorage: 始终有效(设定的时间内)。

Cookie sessionStorage localStorage作用

  • cookie:保存用户登录状态;跟踪用户行为

Cookie如何防范xss攻击

  • XSS(跨站脚本攻击)是指攻击者在返回的HTML中嵌入js脚本,为了减轻这些攻击,需要http头部配上set-cookie:
  • http-only: 可以防止xss,它会禁止js脚本访问cookie
  • secure: 这个属性告诉浏览器仅在请求为https的时候发送cookie
  • 结果:Set-cookie=...

csrf和xss的网络攻击和防范

  • CSRF:跨站请求伪造,可以理解为攻击者盗用了用户的身份,以用户的名义发送了恶意请求。
    • ​ 防御方式:使用验证码;检查http头部的refer;使用token
  • XSS:跨站脚本攻击,是说攻击者通过注入恶意的脚本,在用户浏览网页的时候进行攻击,比如获取cookie或者其他用户信息,可以分为存储型和反射型
    • 防御方式:配置set-cookie;对用户输入进行检查;进行特殊字符过滤。

CSS

回流和重绘

  • 回流:当我们对 DOM 的修改引发了 DOM 几何尺寸的变化(比如修改元素的宽、高或隐藏元素等)时,浏览器需要重新计算元素的几何属性(其他元素的几何属性和位置也会因此受到影响),然后再将计算的结果绘制出来。这个过程就是回流(也叫重排)。
  • 重绘:当我们对 DOM 的修改导致了样式的变化、却并未影响其几何属性(比如修改了颜色或背景色)时,浏览器不需重新计算元素的几何属性、直接为该元素绘制新的样式(跳过了上图所示的回流环节)。这个过程叫做重绘。
  • 重绘不一定导致回流,回流一定会导致重绘。回流比重绘做的事情更多,带来的开销也更大。在开发中,要从代码层面出发,尽可能把回流和重绘的次数最小化。

JavaScript !!!!!

ES6新特性

  • let 和 const
    • 不会导致变量提升。
    • const : 定义常量;常量不可以修改
console.log(a); // undefined
var  a = 100;

console.log(a); // 报错
let a = 111;
  • 块级作用域

    • 提供代码的运行环境
    • 存储基本数据类型值
  • 变量的解析赋值

    • 解构的值一定是可遍历的
    • 如果解构不成功,存储值是undefined;
    let [x,y,z] = [1,2];
    console.log(x); // 1
    console.log(y); // 2
    console.log(z); // undefined
    
    let [a,[b],c]=[1,[2],3]
    console.log(a); // 1
    console.log(b); // 2
    console.log(c); // 3
    • 对象的解构与顺序无关,根据key解构
  • 数组拓展

    • Array.from:将类数组转换成一个真正的数组;
    • Array.of:将一组数转换成数组;
    • 剩余运算符(...ary)
  • 箭头操作符

    • 简化了函数的书写。操作符左边为输入的参数,而右边则是进行的操作以及返回的值Inputs=>outputs。
  • 类的支持 class

    • 实际上只是JS原型模式的包装
    //类的定义
    class Animal {
    	//ES6中新型构造器
        constructor(name) {
            this.name = name;
        }
        //实例方法
        sayName() {
            console.log('My name is '+this.name);
        }
    }
    //类的继承
    class Programmer extends Animal {
        constructor(name) {
        	//直接调用父类构造器进行初始化
            super(name);
        }
        program() {
            console.log("I'm coding...");
        }
    }
    
  • 字符串模板

    • //产生一个随机数
      var num=Math.random();
      //将这个数字输出到console
      console.log(`your num is ${num}`);
  • for of遍历

    • 每次循环它提供的不是序号而是值

    • for in 提供的是序号;for…in 语句以任意顺序迭代对象的可枚举属性

    • for…of 语句遍历可迭代对象定义要迭代的数据

    • Object.prototype.objCustom = function() {}; 
      Array.prototype.arrCustom = function() {};
      
      let iterable = [3, 5, 7];
      iterable.foo = 'hello';
      
      for (let i in iterable) {
        console.log(i); // logs 0, 1, 2, "foo", "arrCustom", "objCustom"
      }
      
      for (let i in iterable) {
        if (iterable.hasOwnProperty(i)) {
          console.log(i); // logs 0, 1, 2, "foo"
        }
      }
      
      for (let i of iterable) {
        console.log(i); // logs 3, 5, 7
      }
  • Map,Set

  • Proxies

    • 可以监听对象身上发生了什么事情

    • 让我们对一个对象有了很强的追踪能力,同时在数据绑定方面也很有用处

    • //定义被侦听的目标对象
      var engineer = { name: 'Joe Sixpack', salary: 50 };
      //定义处理程序
      var interceptor = {
        set: function (receiver, property, value) {
          console.log(property, 'is changed to', value);
          receiver[property] = value;
        }
      };
      //创建代理以进行侦听
      engineer = Proxy(engineer, interceptor);
      //做一些改动来触发代理
      engineer.salary = 60;//控制台输出:salary is changed to 60
  • 对Math,Number,String还有Object等添加了许多新的API

  • Promises

    • 处理异步
    • 三种状态:pending 等待,fufiled 实现, rejected拒绝
    • promise.all([p1,p2,p3]).then 。即p1p2p3全部成功后才调用.then
    • Promise.race([p1,p2,p3]).then 。一个完成则执行,不会影响其他promise执行

JS进行DOM操作

  • 节点概述

    • 在网页中所有的对象和内容都被称为节点,如文档元素文本属性注释等。节点(Node)是DOM最基本的单元,并派生出不同类型的节点,它们共同构成了文档的树形结构模型
  • 节点类型

    • 根据DOM规范,整个文档是一个文档节点,每个标签是一个元素节点,元素包含的文本是文本节点,元素的属性是一个属性节点,注释属于注释节点
    节点类型 说明 可包含的字节类型 nodeType属性判断节点类型
    Document 表示整个文档,DOM树的根节点 Element、ProcessingInstruction、Comment、DocumentType 9
    DocumentFragment 表示文档片段,轻量级的Document对象,仅包含部分文档 ProcessingInstruction、Comment、Text、CDATASection、EntityReference 11
    DocumentType 为文档定义实体提供接口 None 10
    Element 表示元素 Text、Comment、ProcessingInstruction、CDATASection、EntityReference 1
    Attr 表示属性 Text、EntityReference 2
    Text 表示元素或属性中的文本 None 3
    。。。 。。。 。。。
  • 访问节点

    • ownerDocument:返回当前节点的根元素(document对象)。
    • parentNode:返回当前节点的父节点,所有的节点都仅有一个父节点。
    • childNodes:返回当前节点的所有子节点的节点列表。
    • firstChild:返回当前节点的第一个子节点。
    • lastChild:返回当前节点的最后一个子节点。
    • nextSibling:返回当前节点之后相邻的同级节点。
    • previousSibling:返回当前节点之前相邻的同级节点。
    • 注意:firstChild等价于childNodes的第一个元素,lastChild属性值等于childNodes的最后一个元素。如果firstChild等于null,则说明当前节点为空节点。
  • 操作节点

    方法 说明
    appendChild() 向节点的子节点列表的结尾添加新的子节点
    cloneNode() 复制节点
    hasChildNodes() 判断当前节点是否拥有子节点
    insetBefore() 在指定的子节点前插入新的子节点
    normalize() 合并相邻的Text节点并删除
    removeChild() 删除(并返回)当前节点的指定子节点
    replaceChild() 用新节点替换一个子节点
    • 提示:appendChild()、insertBefore()、removeChild()、replaceChild()四个方法用于对子节点进行操作。使用者四个方法之前,可以使用parentNode属性先获取父节点。
  • 文档节点

    • 文档节点代表整个文档,使用document可以访问。它是文档内其他节点的访问入口,提供了操作其他节点的方法。
    • 访问文档
      • 文档内部节点,使用ownerDocument访问。
      • 脚本中,使用document访问。
      • 框架页,使用contentDocument访问。
      • 异步通信中,使用XMLHttpRequest对象的responseXML访问。
    • 访问文档元素
      • getElementById():返回指定id属性值的元素。注意,id值要区分大小写。,如果找到多个id相同的元素,则返回第一个元素;如果没有找到指定id值的元素,则返回null。
      • getElementsByTagName():返回所有指定标签名的元素节点。
      • getElementsByname():返回指定名称(name属性值)的元素节点。该方法多用于表单结构中,获取单选按钮组或复选框组。
    • 访问子节点
      • 使用document.documentElement可以访问html元素。
      • 使用document.doctype可以访问doctype。注意,部分浏览器不支持。
      • 使用document.childNodes可以遍历子节点。
      • 使用document.firstChild可以访问第一个子节点,一般为doctype。
      • 使用docuemnt.lastChild可以访问最后一个子节点,如html元素或注释。
    • 访问特殊元素
      • 使用document.body可以访问body元素。
      • 使用documetn.head可以访问head元素。
      • 使用document.defaultView可以访问默认制图,即所属的窗口对象window。
      • 使用document.scrollingElement可以访问文档内滚动的元素。
      • 使用document.activeElement可以访问文档内获取焦点的元素。
      • 使用document.fullscreenElement可以访问文档内正在全屏显示的元素。
    • 访问元素集合
      • document.anchors:返回设置name属性的<a>标签。
      • document.links:返回所有设置了href属性的<a>标签。
      • document.forms:返回所有form对象。
      • document.images:返回所有image对象。
      • document.applets:返回所有applet对象。
      • document.enbeds:返回所有enbed对象。
      • document.plugins:返回所有plugin对象。
      • document.scripts:返回所有的script对象。
      • document.styleSheets:返回所有样式表集合。
    • 访问文档信息
      • document.URL:返回当前文档的网址。
      • document.domain:返回当前文档的域名,不包含协议和接口。
      • document.location:访问location对象。
      • docuemnt.lastModified:返回当前文档最后修改的时间。
      • document.title:返回当前文档的标签。
      • document.characterSet:返回当前文档的编码。
      • document.referrer:返回当前文档的访问者在哪里。
      • document.dir:返回文字方向。
      • document.compatMode:返回浏览器处理文档的模式,值包括BackCompat(向后兼容模式)和CSS1Compat(严格模式)。
      • document.hidden:表示当前页面是否可见。如果窗口最小化、切换页面,则document.hidden返回true。
      • document.visibilitystate:返回文档的可见状态。取值包括visible(可见)、hidden(不可见)、prerender(正在渲染)、unloaded(已卸载)。
      • document.readyState:返回当前文档的状态、取值包括loading(正在加载)、interactive(加载外部资源)、complete(加载完成)。
  • 元素节点

    • nodeType等于1。nodeName等于标签名、nodeValue等于null。
    • 包含5个公共属性:
      • id(标识符)、
      • title(提示标签)、
      • lang(语言编码)、
      • dir(语言方向)、
      • className(CSS类样式)
    • 访问元素
      • getElementById():返回指定id属性值的元素。注意,id值要区分大小写。,如果找到多个id相同的元素,则返回第一个元素;如果没有找到指定id值的元素,则返回null。
      • getElementsByTagName():返回所有指定标签名的元素节点。
      • getElementsByname():返回指定名称(name属性值)的元素节点。该方法多用于表单结构中,获取单选按钮组或复选框组。
      • getElementByClassName()方可以接受一个字符串参数,包括一个或多个类名.(H5新增)
      • 可迭代使用:如document.getElementById("box").getElementsByClassName("blue red");
    • 创建元素
      • var element = document.createElement("tagName");根据标签名创建
    • 复制节点
      • cloneNode()方法
    • 插入节点
      • document.getElementById("box").appendChild(新节点);
      • insertBefore(newchild, refchild); newchild表示新插入的节点,refchild表示插入新节点的节点
    • 删除节点
      • nodeObject.removeChild(node)
    • 替换节点
      • nodeObject.replaceChild(new_node, old_node)
  • 文本节点

    • 创建文本节点
      • document.createTextNode(data)
    • 访问文本节点
      • 获取元素后遍历,nodeType == 3,使用nodeValue或data属性访问内容
  • 属性节点

    • 创建属性节点

      • document.createAttribute(attr),参数attr表示新创建的属性的名称
    • 设置属性值

      • setAttribute(attr属性名称, value属性值);
      • 也可以使用快捷方式设置HTML DOM文档中元素的属性值。
        • var label = document.getElementByIn("label1");
        • label.className = "class1";
        • label.htmlFor = "textfield";
    • 为元素节点添加属性节点

      • element.setAttributeNode(attr);

      • 在传统DOM中,常用点语法通过元素直接访问HTML属性,如img.src、a.href等,这种方式虽然不标准,但是获得了所有浏览器的支持。

        • <img id="img1" src="">
          <script>
          	var img = document.getElementByIn("img1");	
          	img.setAttribute("src","http://www.w3.org/");
          	img.str = "http://www.w3.org/";
          </script>
    • 获取属性节点

      • element.getAttribute("attr")
      • element.getAttributeNode("attr").value
      • element.attributes["attr"].value
  • 文档片段节点

    • 创建文档片段的方法
      • var fragment = document.createDocumentFragment();
    • 为什么使用
      • 每次使用js操作DOM都会改变页面呈现,并触发整个页面重新渲染(回流),从而消耗系统资源。为了解决这个问题,可以先创建一个文档片段,把所有新节点附加到文档片段上,最后再把文档片段一次性添加到文档中,减少页面重绘次数
  • CSS选择器

    • querySelector(‘css选择语句’)。
    • querySelectorAll(‘css选择语句’)
    • 提示:DOM API模块也包含getElementByClassName()方法,使用该方法可以获取指定类名的元素。
    • 注意:getElementByClassName()方法只能够接受字符串,且为类名,而不需要加点号前缀,如果没有匹配到任何元素则返回空数组。
  • HTML字符串

    • 读取

      • 使用元素的innerHTML属性可以返回调用元素包含的所有子节点对应的HTML标记字符串。
    • 插入、替换

      • 根据传入的HTML字符串,创建新的DOM片段
      • 替代调用元素原有的所有子节点
      • 使用innerHTML属性也有一些限制。例如,在大多数浏览器中,通过innerHTML插入<script>标记后,并不会执行其中的脚本。

jQuery

BootStrap

前端核心

服务端

Ajax

移动web开发

前端进阶

前端优化

  • 代码优化
    • js优化
    • html优化
    • css优化
  • 渲染优化
    • 现代浏览器渲染原理
    • 可优化的渲染环节和方法
  • 资源优化
    • 压缩与合并
    • 图片格式
    • 图片加载
    • 字体优化
  • 构建优化
    • webpack的优化配置
    • 代码拆分
    • 代码压缩
    • 持久化缓存
    • 监测与分析
    • 按需加载
  • 传输加载优化
    • Gzip
    • keepAlive
    • Http缓存
    • service worker
    • http/2
    • ssr
    • nginx
  • 更多流行优化技术
    • svg优化图标
    • flexbox布局
    • 预加载
    • 预渲染
    • 窗口化提高列表性能
    • 骨架组件

降低请求量

  • 合并资源
  • 减少HTTP请求数
  • minify/zip压缩
  • webP
  • lazyLoad

加快请求速度

  • 预渲染DNS
  • 减少域名数
  • 并行加载
  • CDN分发

缓存

  • HTTP协议缓存请求
  • 离线缓存manifest
  • 离线数据缓存localstorage

渲染

  • JS/CSS优化
    • css优化:避免使用通配符;少用标签选择器多用类选择器;减少嵌套
  • 加载顺序
  • 服务端渲染
  • pipeline

其他

  • 避免多次全局查找。如若需多次用vuex的数据时可以先存储为局部变量
  • 小心使用闭包
  • 图片优化
    • 减少像素点
    • 减少每个像素点能够显示的颜色

前端工作流

流行框架

模块化开发

Node.js

移动端开发

混合式应用开发

React

计算机基础

计算机网络

操作系统

数据库

算法和数据结构

递归

排序

  • 稳定:如果a原本在b前面,而a=b,排序之后a仍然在b的前面。
  • 不稳定:如果a原本在b的前面,而a=b,排序之后 a 可能会出现在 b 的后面。
  • 时间复杂度:对排序数据的总的操作次数。反映当n变化时,操作次数呈现什么规律。
  • **空间复杂度:**是指算法在计算机内执行时所需存储空间的度量,它也是数据规模n的函数。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aiduzW1P-1602918160158)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201009142806429.png)]

冒泡排序
  • 比较相邻的元素。
  • 如果第一个比第二个大,就交换它们两个;
function bubbleSort(arr) {
    const len = arr.length;
    for(let i = 0; i < len - 1; i++) {
        for(let j = 0; j < len - 1 - i; j++) {
            if(arr[j] > arr[j+1]) {        // 相邻元素两两对比
                const temp = arr[j+1];        // 元素交换
                arr[j+1] = arr[j];
                arr[j] = temp;
            }
        }
    }
    return arr;
}
选择排序
  • 在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,
  • 然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾
function selectionSort(arr) {
    const len = arr.length;
    let minIndex, temp;
    for(let i = 0; i < len - 1; i++) {
        minIndex = i;
        for(let j = i + 1; j < len; j++) {
            if(arr[j] < arr[minIndex]) {     // 寻找最小的数
                minIndex = j;                 // 将最小数的索引保存
            }
        }
        temp = arr[i];
        arr[i] = arr[minIndex];
        arr[minIndex] = temp;
    }
    return arr;
} 
插入排序
  • 从第一个元素开始,该元素可以认为已经被排序;
  • 取出下一个元素,在已经排序的元素序列中从后向前扫描;
  • 如果该元素(已排序)大于新元素,将该元素移到下一位置;
  • 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;
  • 将新元素插入到该位置后;
  • 重复步骤2~5。
function insertionSort(arr) {
    let len = arr.length;
    let preIndex, current;
    for(let i = 1; i < len; i++) {
        preIndex = i - 1;
        current = arr[i];
        while(preIndex >= 0 && arr[preIndex] > current) {
            arr[preIndex + 1] = arr[preIndex];
            preIndex--;
        }
        arr[preIndex + 1] = current;
    }
    return arr;
}
希尔排序
  • 简单插入排序的改进版

  • 会优先比较距离较远的元素

  • 选择一个增量序列t1,t2,…,tk,其中ti>tj,tk=1;

  • 按增量序列个数k,对序列进行k 趟排序;

  • 每趟排序,根据对应的增量ti,将待排序列分割成若干长度为m 的子序列,分别对各子表进行直接插入排序。仅增量因子为1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。

let arr = [49, 38, 65, 97, 76, 13, 27, 49, 55, 04];
let len = arr.length;
// 增量为fraction
for (let fraction = Math.floor(len / 2); fraction > 0; fraction = Math.floor(fraction / 2)) {
    console.log('fraction',fraction);
    // 对分组进行直接插入排序
    for (let i = fraction; i < len; i++) {
        // 插入排序
        for (let j = i - fraction; j >= 0 && arr[j] > arr[fraction + j]; j -= fraction) {
            let temp = arr[j];
            arr[j] = arr[fraction + j];
            arr[fraction + j] = temp;
        }
    }
    console.log(arr);
}
console.log(arr);
堆排序
快速排序
  • 从数列中挑出一个元素,称为 “基准”(pivot);
  • 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;
  • 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
function quickSort(arr, left, right) {
    var len = arr.length,
        partitionIndex,
        left = typeof left != 'number'? 0 : left,
        right = typeof right != 'number'? len - 1 : right;
 
    if(left < right) {
        partitionIndex = partition(arr, left, right);
        quickSort(arr, left, partitionIndex-1);
        quickSort(arr, partitionIndex+1, right);
    }
    return arr;
}
 
function partition(arr, left ,right) {     // 分区操作
    var pivot = left,                      // 设定基准值(pivot)
        index = pivot + 1;
    for(var i = index; i <= right; i++) {
        if(arr[i] < arr[pivot]) {
            swap(arr, i, index);
            index++;
        }       
    }
    swap(arr, pivot, index - 1);
    return index-1;
}
 
function swap(arr, i, j) {
    var temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
}
归并排序
  • 把长度为n的输入序列分成两个长度为n/2的子序列;
  • 对这两个子序列分别采用归并排序;
  • 将两个排序好的子序列合并成一个最终的排序序列
function mergeSort(arr) {
    varlen = arr.length;
    if(len < 2) {
        returnarr;
    }
    var middle = Math.floor(len / 2),
        left = arr.slice(0, middle),
        right = arr.slice(middle);
    return merge(mergeSort(left), mergeSort(right));
}
 
function merge(left, right) {
    var result = [];
 
    while(left.length>0 && right.length>0) {
        if(left[0] <= right[0]) {
            result.push(left.shift());
        } else{
            result.push(right.shift());
        }
    }
 
    while(left.length)
        result.push(left.shift());
 
    while(right.length)
        result.push(right.shift());
 
    return result;
}

查找

设计模式

装饰模式

单例模式

工厂方法模式

观察者模式

场景题

自我介绍

来自哪里

什么时候开始接触前端

做了什么项目,用了什么技术,有什么收获。

项目

智慧营销系统
  • 是干什么的

    • 负责项目可复用组件的开发、新页面的重构和开发
    • 基于element-ui进行组件重封装
    • 表单组件
  • 具体工作

    • 因为项目已经开发到半途,所以首先熟悉新项目。看文档/规范/代码
    • 进行简单的页面样式修改,进一步熟悉项目代码风格
    • 进行组件的修改
    • 开始进行页面重构
    • 开发新组件
    • 开发新页面
  • 难点/收获

    • 接触了一些之前没有接触过的内容。严格的页面配置、二维码绘制后的本地保存(涉及到跨域)、

响应式布局常用解决方案

  1. px和视口

    css像素 为web开发者提供,在css中使用的一个抽象单位
    物理像素 只与设备的硬件密度有关,任何设备的物理像素都是固定的

    广义的视口,是指浏览器显示内容的屏幕区域,狭义的视口包括了布局视口、视觉视口和理想视口:

    (1) 布局视口(layout viewport)

    布局视口定义了pc网页在移动端的默认布局行为,因为通常pc的分辨率较大,布局视口默认为980px。也就是说在不设置网页的viewport的情况下,pc端的网页默认会以布局视口为基准,在移动端进行展示。因此我们可以明显看出来,默认为布局视口时,根植于pc端的网页在移动端展示很模糊。

    (2) 视觉视口(visual viewport)

    视觉视口表示浏览器内看到的网站的显示区域,用户可以通过缩放来查看网页的显示内容,从而改变视觉视口。视觉视口的定义,就像拿着一个放大镜分别从不同距离观察同一个物体,视觉视口仅仅类似于放大镜中显示的内容,因此视觉视口不会影响布局视口的宽度和高度。

    (3) 理想视口(ideal viewport)

    理想视口或者应该全称为“理想的布局视口”,在移动设备中就是指设备的分辨率。换句话说,理想视口或者说分辨率就是给定设备物理像素的情况下,最佳的“布局视口”。

  2. 媒体查询

    使用@media可以针对不同的媒体类型定义不同的样式

    @media screen and (max-width: 960px){
        body{
          background-color:#FF6699
        }
    }
    
    @media screen and (max-width: 768px){
        body{
          background-color:#00FF66;
        }
    }
    
    @media screen and (max-width: 550px){
        body{
          background-color:#6633FF;
        }
    }
    
    @media screen and (max-width: 320px){
        body{
          background-color:#FFFF00;
        }
    }

    通过媒体查询,可以通过给不同分辨率的设备编写不同的样式来实现响应式的布局,比如我们为不同分辨率的屏幕,设置不同的背景图片。比如给小屏幕手机设置@2x图,为大屏幕手机设置@3x图,通过媒体查询就能很方便的实现。

    但是媒体查询的缺点也很明显,如果在浏览器大小改变时,需要改变的样式太多,那么多套样式代码会很繁琐。

  3. 百分比

    对于百分比单位的介绍我们很容易看出如果全部使用百分比单位来实现响应式的布局,有明显的以下两个缺点:

    (1)计算困难,如果我们要定义一个元素的宽度和高度,按照设计稿,必须换算成百分比单位。
    (2)从小节1可以看出,各个属性中如果使用百分比,相对父元素的属性并不是唯一的。比如width和height相对于父元素的width和height,而margin、padding不管垂直还是水平方向都相对比父元素的宽度、border-radius则是相对于元素自身等等,造成我们使用百分比单位容易使布局问题变得复杂。

  4. 自适应场景下的rem解决方案

    rem是一个灵活的、可扩展的单位,由浏览器转化像素并显示。与em单位不同,rem单位无论嵌套层级如何,都只相对于浏览器的根元素(HTML元素)的font-size

    默认情况下,html元素的font-size为16px,所以:

        1 rem = 16px
    

    为了计算方便,通常可以将html的font-size设置成:

        html{ font-size: 62.5% }
    

    这种情况下:

        1 rem = 10px
    
    • rem 布局的缺点

    通过rem单位,可以实现响应式的布局,特别是引入相应的postcss相关插件,免去了设计稿中的px到rem的计算。rem单位在国外的一些网站也有使用,这里所说的rem来实现布局的缺点,或者说是小缺陷是:

    在响应式布局中,必须通过js来动态控制根元素font-size的大小。

    也就是说css样式和js代码有一定的耦合性。且必须将改变font-size的代码放在css样式之前。

  5. vw / vh

    单位 含义
    vw 相对于视窗的宽度,视窗宽度是100vw
    vh 相对于视窗的高度,视窗高度是100vh
    vmin vw和vh中的较小值
    vmax vw和vh中的较大值

    vw和%的区别为:

    单位 含义
    % 大部分相对于祖先元素,也有相对于自身的情况比如(border-radius、translate等)
    vw/vh 相对于视窗的尺寸

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions