前端事件流

事件流程如下:

  1. 捕获阶段:事件从根元素开始向触发事件的目标元素进行传递,传递过程中,如果中间有元素注册了事件处理函数,并且 useCapture 参数值为 true ,那么此事件处理函数就会执行,IE9+和其他标准浏览器支持。

  2. 目标阶段:触发目标元素对应事件,并执行注册的事件处理函数。

  3. 冒泡阶段:从目标元素开始向根元素传递,传递过程中,如果中间有元素注册了事件处理函数,且 useCapture 值为 false,此事件处理函数就会执行。

什么是闭包?这就是闭包!

有权访问另一个函数作用域内变量的函数都是闭包。

HTTP缓存机制和原理

  1. 强制缓存

    https://jangdelong.github.io/blog_img/images/1.png

    (1) Expires

    Expires 的值为服务端返回的到期时间,即下一次请求时,请求时间小于服务端返回的到期时间,直接使用缓存数据。

    不过 Expires 是HTTP 1.0的东西,现在默认浏览器均默认使用 HTTP 1.1,所以它的作用基本忽略。

    另一个问题是,到期时间是由服务端生成的,但是客户端时间可能跟服务端时间有误差,这就会导致缓存命中的误差。

    所以HTTP 1.1 的版本,使用Cache-Control替代。

    (2) Cache-Control

    Cache-Control 是最重要的规则。常见的取值有 private、public、no-cache、max-age,no-store,默认为 private。

    • private: 客户端可以缓存
    • public: 客户端和代理服务器都可缓存(前端的同学,可以认为 public 和 private 是一样的)
    • max-age=xxx: 缓存的内容将在 xxx 秒后失效
    • no-cache: 需要使用对比缓存来验证缓存数据(后面介绍)
    • no-store: 所有内容都不会缓存,强制缓存,对比缓存都不会触发(对于前端开发来说,缓存越多越好,so…基本上和它说886)
  2. 对比缓存

    https://jangdelong.github.io/blog_img/images/2.png

    (1) Last-Modified / If-Modified-Since

    • Last-Modified:

      服务器在响应请求时,告诉浏览器资源的最后修改时间。

      https://jangdelong.github.io/blog_img/images/3.png

    • If-Modified-Since:

      再次请求服务器时,通过此字段通知服务器上次请求时,服务器返回的资源最后修改时间。
      服务器收到请求后发现有头 If-Modified-Since 则与被请求资源的最后修改时间进行比对。
      若资源的最后修改时间大于 If-Modified-Since,说明资源又被改动过,则响应整片资源内容,返回状态码 200;

      若资源的最后修改时间小于或等于 If-Modified-Since,说明资源无新修改,则响应HTTP 304,告知浏览器继续使用所保存的cache。

      https://jangdelong.github.io/blog_img/images/4.png

      (2) Etag / If-None-Match (优先级高于Last-Modified / If-Modified-Since)

    • Etag:

      服务器响应请求时,告诉浏览器当前资源在服务器的唯一标识(生成规则由服务器决定)。

      https://jangdelong.github.io/blog_img/images/5.png

    • If-None-Match:

      再次请求服务器时,通过此字段通知服务器客户段缓存数据的唯一标识。

      服务器收到请求后发现有头 If-None-Match 则与被请求资源的唯一标识进行比对,
      不同,说明资源又被改动过,则响应整片资源内容,返回状态码 200;

      相同,说明资源无新修改,则响应 HTTP 304,告知浏览器继续使用所保存的 cache。

      https://jangdelong.github.io/blog_img/images/6.png

defer 和 async

  1. defer

如果 script 标签设置了该属性,则浏览器会异步的下载该文件并且不会影响到后续 DOM 的渲染;

如果有多个设置了 defer 的 script 标签存在,则会按照顺序执行所有的 script;

defer 脚本会在文档渲染完毕后,DOMContentLoaded 事件调用前执行。

  1. async

async 的设置,会使得 script 脚本异步的加载并在允许的情况下执行;
async 的执行,并不会按着 script 在页面中的顺序来执行,而是谁先加载完谁执行。

使用 js 的 FileReader对象实现上传图片时的图片预览功能

废话不多说线上代码

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1, user-scalable=no">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="format-detection" content="telephone=no">
<title>test</title>
<script>
  // 选择图片时预览功能
function imageshow(source) {
var file = source.files[0];
var imageid = source.id;
if (window.FileReader) {
var fr = new FileReader();
fr.onloadend = function (e) {
document.getElementById("portrait"+imageid).src = e.target.result;
};
fr.readAsDataURL(file);
}
    document.getElementById("image"+imageid).style.display="none";
document.getElementById("show"+imageid).style.display="block";
   }
</script>
</head>

<body>
<div>
<div id="image1" >
<p>上传截图</p>
<input type="file" name="screenshot1" id="1" onchange="imageshow(this)"/>
</div>

 <div id="show1" style="display:none;">
  <img src="" id="portrait1" width="100" height="70">
 </div>

 <div id="image2">
<p>上传截图</p>
<input type="file" name="screenshot2" id="2" onchange="imageshow(this)"/>
</div>

 <div id="show2" style="display:none;">
  <img src="" id="portrait2" width="100" height="70">
 </div>

<div id="image3">
<p>上传截图</p>
<input type="file" name="screenshot3" id="3" onchange="imageshow(this)"/>
</div>

<div id="show3" style="display:none;">
  <img src="" id="portrait3" width="100" height="70" >
 </div>
</div>
</body>
</html>

HTTPS 验证原理

https 在真正请求数据前,先会与服务有几次握手验证,以证明相互的身份,以下图为例

https://jangdelong.github.io/blog_img/images/front-end-notes/7.png

性能优化

  • 减少请求数量(sprite、combo)
  • 善用缓存(application cache、http缓存、CDN、localstorage、sessionstorage,备忘录模式)
  • 减少选择器消耗(从右到左),减少DOM操作(DOM和JavaScript解释器的分离)
  • CSS的回流与重绘

对称加密及非对称加密

  • 对称加密

发送方和接收方需要持有同一把密钥,发送消息和接收消息均使用该密钥。

相对于非对称加密,对称加密具有更高的加解密速度,但双方都需要事先知道密钥,密钥在传输过程中可能会被窃取,因此安全性没有非对称加密高。

  • 非对称加密算法

接收方在发送消息前需要事先生成公钥和私钥,然后将公钥发送给发送方。发送放收到公钥后,将待发送数据用公钥加密,发送给接收方。接收到收到数据后,用私钥解密。
在这个过程中,公钥负责加密,私钥负责解密,数据在传输过程中即使被截获,攻击者由于没有私钥,因此也无法破解。

非对称加密算法的加解密速度低于对称加密算法,但是安全性更高。

—- 以下更新于 2018-12-11 —-

  • 从属关系区别

@import是 CSS 提供的语法规则,只有导入样式表的作用;link是HTML提供的标签,不仅可以加载 CSS 文件,还可以定义 RSS、rel 连接属性等。

  • 加载顺序区别

加载页面时,link标签引入的 CSS 被同时加载;@import引入的 CSS 将在页面加载完毕后被加载。

  • 兼容性区别

@import是 CSS2.1 才有的语法,故只可在 IE5+ 才能识别;link标签作为 HTML 元素,不存在兼容性问题。

  • DOM可控性区别

可以通过 JS 操作 DOM ,插入link标签来改变样式;由于 DOM 方法是基于文档的,无法使用@import的方式插入样式。

CSS 权重优先级顺序

!important > 行内样式 > ID > 类、伪类、属性 > 标签名 > 继承 > 通配符

观察者模式

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
/* Pubsub */
function Pubsub () {
//存放事件和对应的处理方法
this.handles = {};
}
Pubsub.prototype = {
//传入事件类型type和事件处理handle
on: function (type, handle) {
if(!this.handles[type]){
this.handles[type] = [];
}
this.handles[type].push(handle);
},
emit: function () {
// 通过传入参数获取事件类型
var type = Array.prototype.shift.call(arguments);
if (!this.handles[type]) {
return false;
}
for (var i = 0; i < this.handles[type].length; i++) {
var handle = this.handles[type][i];
// 执行事件
handle.apply(this, arguments);
}
},
off: function (type, handle) {
handles = this.handles[type];
if (handles) {
if (!handle) {
handles.length = 0; // 清空数组
} else {
for (var i = 0; i < handles.length; i++) {
var _handle = handles[i];
// 有点问题
if (_handle === handle) {
handles.splice(i,1);
}
}
}
}
}
}

两大数相加

1
2
3
4
5
6
7
8
9
10
11
12
function sumStrings (a, b) {
var res = '',
c = 0;
a = a.split('');
b = b.split('');
while (a.length || b.length || c) {
c += ~~a.pop() + ~~b.pop(); // ~~a字符串转数字
res = c % 10 + res;
c = c > 9; // 进1
}
return res.replace(/^0+/,'');
}

设备像素比

物理像素(physical pixel)

一个物理像素是显示器(手机屏幕)上最小的物理显示单元,在操作系统的调度下,每一个设备像素都有自己的颜色值和亮度值。

设备独立像素(density-independent pixel)

设备独立像素(也叫密度无关像素),可以认为是计算机坐标系统中得一个点,这个点代表一个可以由程序使用的虚拟像素(比如: css像素),然后由相关系统转换为物理像素。 所以说,物理像素和设备独立像素之间存在着一定的对应关系,这就是接下来要说的设备像素比。

设备像素比(device pixel ratio )

设备像素比(简称dpr)定义了物理像素和设备独立像素的对应关系,它的值可以按如下的公式的得到:

1
设备像素比 = 物理像素 / 设备独立像素 // 在某一方向上,x方向或者y方向

—- 以下更新于 2018-12-13 —-

双向绑定原理(简单思路)

  1. 实现一个监听器Observer,用来劫持并监听所有属性,如果有变动的,就通知订阅者。

  2. 实现一个订阅者Watcher,每一个Watcher都绑定一个更新函数,watcher可以收到属性的变化通知并执行相应的函数,从而更新视图。

  3. 实现一个解析器Compile,可以扫描和解析每个节点的相关指令(v-model,v-on等指令),如果节点存在v-model,v-on等指令,则解析器Compile初始化这类节点的模板数据,使之可以显示在视图上,然后初始化相应的订阅者(Watcher)。