垃圾桶

没有绝对的垃圾,点石成金,变废为宝

全栈知识体系

前端知识体系

  • 标识符注解

    • 已完成 ✅
    • 进行中 💹
    • 未开始 ❎
  • HTML

    • SEO ❎
    • 语义化 ❎
    • doctype ❎
    • link 与@import ❎
    • async 与 defer ❎
    • 渐进增强与优雅降级 ❎
    • 捕捉,冒泡与委托 ❎
    • 元素标签分类 ❎
    • iframe ❎
    • 预解析/预加载/预渲染 ❎
  • CSS

    • 清除浮动 ❎
    • 选择器 + 优先级 ❎
    • 多边形绘制 ❎
    • 兼容 Hack ❎
    • BFC ❎
    • 盒模型 ❎
    • Flex ❎
    • CSS 3 ❎
    • Grid ❎
    • 媒体查询:响应式栅格化 ❎
    • 媒体单位:px,em.rem,vw/vh ❎
    • 居中 ❎
    • 瀑布流 ❎
    • 轮播图 ❎
    • 伪类和伪元素 ❎
    • 多边形绘制
    • 精灵图
    • 预处理库 SASS
  • JS

    • 事件循环/宏任务/微任务
    • 冒泡、捕获、委托、阻止事件冒泡、阻止事件的默认行为、滚动阻止事件的默认行为、单次调用
    • 原始类型/对象类型
    • 闭包
    • 执行上下文
    • 继承/原型/原型链
    • this
    • proto/prototype
    • 作用链域
    • 继承
    • new 关键字
    • Promise/Async/Await
    • 类型的判断
    • 运算精度
    • 拷贝
    • 函数调用模式
    • 高阶函数
    • 柯里化函数
    • 严格模式
    • websocket
    • Proxy 对比 defineProperty
  • 框架

    • VUE
      • 对 Vue 的了解
      • Vue 响应式原理
      • Vue 生命周期 (11 个)
      • Vue 单向绑定,Vue 双向绑定
      • Vue 异步更新队列
      • Vue 虚拟 Dom 和 Diff 算法
      • Vue 和 React 的区别
      • Vue 如何监听数组和对象
      • Vue Router 前端路由原理
      • Vue filters 过滤器
      • Vue directives 指令和自定义指令
      • Vue 组件通信
  • 构建工具

  • 网络

    • 解释下 https 的连接过程
    • 解释 tcp 的三次握手和四次挥手
    • 浏览器输入 URL 后做了什么?
    • 浏览器如何加载网页并呈现?
    • 跨域与 JSONP
    • 浏览器端存储的方式
    • 解释 xss 和 csrf,及其防范
  • 动画

  • TS

  • 优化

    • 首屏优化

数据结构和算法

- 队列
- 栈
- 链表
- 字典
- 集合
- 散列
- 二叉树
- 算法复杂度概念
- 算法斐波那契
- 算法求和
- 算法排序
- 算法动态规划
- 算法贪心算法
- 算法广度优先
- 算法深度优先

SEO

  • 核心信息 title、description、keywords、h1

    • title 值强调重点即可,重要关键词出现不要超过 2 次,而且要靠前,不同页面 title 要有所不同;
    • description 把页面内容高度概括,长度合适,不可过分堆砌关键词,不同页面 description 有所不同;
    • keywords 列举出重要关键词即可
    • h1 标签页面大标题
  • 重要内容不要用 js 输出:爬虫不会执行 js 获取内容

  • 少用 iframe:搜索引擎不会抓取 iframe 中的内容

  • 静态化页面

  • 外链,用户自发分享最好

  • 完整内链,网站地图

  • 网站内容定期更新

  • 重要内容 HTML 代码放在最前:搜索引擎抓取 HTML 顺序是从上到下,有的搜索引擎对抓取长度有限制,保证重要内容一定会被抓取

  • 语义化的 HTML 代码,符合 W3C 规范:语义化代码让搜索引擎容易理解网页

  • 非装饰性图片必须加 alt

  • 提高网站速度:网站速度是搜索引擎排序的一个重要指标

JS 浅拷贝和深拷贝

  • js 中数据类型分为基本类型引用类型基本包装类型

    • 基本类型(6 个): Null Undefined Number Boolean Symbol String

      • 基本包装类型(3):Boolean Number String
      • 基本类型存储在栈内存
      • 基本类型赋值都是值传递,不存在浅拷贝和深拷贝
    • 引用类型(2 个):Object Function

      • 引用类型存储在堆内存
      • 引用类型赋值都是引用传递
        • 拷贝就是创建并重写新的引用传递
          • 浅拷贝就是对单个引用类型的创建并重写新的引用传递
          • 深拷贝就是对嵌套引用类型的创建并重写新的引用传递

CSS 盒模型

盒模型

  • 从内到外包括: 内容区域(content), 内边距(padding), 边框(border), 外边距(margin)

  • 标准盒模型 box-sizing : content-box;

    • width = content
  • IE 盒模型 box-sizing : border-box;

    • width = content + padding + border

CSS 定位

  • 垂直水平居中

    • Table cell (早期)

    实时 HTML 编辑器: 格式化 压缩化

    实时 HTML 查看器:

    水平垂直居中
    水平垂直居中
    水平垂直居中
    • absolute + transform

    实时 HTML 编辑器: 格式化 压缩化

    实时 HTML 查看器:

    水平垂直居中

    水平垂直居中

    水平垂直居中

    • Flex

    实时 HTML 编辑器: 格式化 压缩化

    实时 HTML 查看器:

  • 九宫格定位

CSS BFC

块级格式化上下文(block formatting context)

创建规则:

  • 根元素
  • 浮动元素(float 不是 none)
  • 绝对定位元素(position 取值为 absolute 或 fixed)
  • display 取值为 inline-block,table-cell, table-caption,flex, inline-flex 之一的元素
  • overflow 不是 visible 的元素

作用:

  • 可以包含浮动元素
  • 不被浮动元素覆盖
  • 阻止父子元素的 margin 折叠

CSS 外边距折叠

collapsing margins,毗邻的两个或多个 margin 会合并成一个 margin,叫做外边距折叠。

规则如下:

  • 两个或多个毗邻的普通流中的块元素垂直方向上的 margin 会折叠
  • 浮动元素/inline-block 元素/绝对定位元素的 margin 不会和垂直方向上的其他元素的 margin 折叠
  • 创建了块级格式化上下文的元素,不会和它的子元素发生 margin 折叠
  • 元素自身的 margin-bottom 和 margin-top 相邻时也会折叠

CSS 清理浮动

  • 容器元素闭合标签前添加额外元素并设置 clear: both
  • 父元素触发块级格式化上下文(见块级可视化上下文部分)
  • 设置容器元素伪元素进行清理推荐的清理浮动方法
/**
* 在标准浏览器下使用
* 1 content内容为空格用于修复opera下文档中出现
*   contenteditable属性时在清理浮动元素上下的空白
* 2 使用display:table而不是block:可以防止容器和
*   子元素top-margin折叠,这样能使清理效果与BFC,IE6/7 zoom: 1;一致
**/
.clearfix:before,
.clearfix:after {
    content: " "; /* 1 */
    display: table; /* 2 */
}

.clearfix:after {
    clear: both;
}
/* IE 6/7触发hasLayout实现包含浮动 */
.clearfix {
    *zoom: 1;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

BFC (Block fomatting context)

它是页面中的一块渲染区域,并且有一套渲染规则,它决定了其子元素将如何定位,以及和其他元素的关系和相互作用。

  • BFC 特点
    • 同一个 BFC 下外边距会发生折叠。(清除边距折叠)
    • BFC 可以包含浮动的元素。(清除浮动)
    • BFC 可以阻止元素被浮动元素覆盖。(实现两列自适应布局)
  • 触发 BFC
    • body 根元素
    • 浮动元素:float 除 none 以外的值
    • 绝对定位元素:position (absolute、fixed)
    • display 为 inline-block、table-cells、flex
    • overflow 除了 visible 以外的值 (hidden、auto、scroll)

选择器

  • 常用(6):
    • * 通用选择器 :选择所有元素,不参与计算优先级,兼容性 IE6+
    • #X id选择器:选择 id 值为 X 的元素,兼容性:IE6+
    • .X 类选择器: 选择 class 包含 X 的元素,兼容性:IE6+
    • X Y后代选择器: 选择满足 X 选择器的后代节点中满足 Y 选择器的元素,兼容性:IE6+
    • X 元素选择器: 选择标所有签为 X 的元素,兼容性:IE6+
    • :link,:visited,:focus,:hover,:active:选择特定状态的链接元素,顺序 LoVe HAte- : IE4+
  • 兄弟选择器(3):
    • X + Y直接兄弟选择器:在 X 之后第一个兄弟节点中选择满足 Y 选择器的元素,兼容性: IE7+
    • X > Y子选择器: 选择 X 的子元素中满足 Y 选择器的元素,兼容性: IE7+
    • X ~ Y兄弟: 选择 X 之后所有兄弟节点中满足 Y 选择器的元素,兼容性: IE7+
  • 属性选择器(8):
    • [attr]:选择所有设置了 attr 属性的元素,兼容性 IE7+
    • [attr=value]:选择属性值刚好为 value 的元素
    • [attr~=value]:选择属性值为空白符分隔,其中一个的值刚好是 value 的元素
    • [attr|=value]:选择属性值刚好为 value 或者 value-开头的元素
    • [attr^=value]:选择属性值以 value 开头的元素
    • [attr$=value]:选择属性值以 value 结尾的元素
    • [attr=value]*:选择属性值中包含 value 的元素
    • [:checked]:选择单选框,复选框,下拉框中选中状态下的元素,兼容性:IE9+
  • 伪元素选择器(5): X:after, X::after:after 伪元素,选择元素虚拟子元素(元素的最后一个子元素),CSS3 中::表示伪元素,:after 为 IE8+,::after 为 IE9+ :hover:鼠标移入状态的元素,兼容性 a 标签 IE4+, 所有元素 IE7+ :not(selector):选择不符合 selector 的元素。不参与计算优先级,兼容性:IE9+ ::first-letter:伪元素,选择块元素第一行的第一个字母,兼容性 IE5.5+ ::first-line:伪元素,选择块元素的第一行,兼容性 IE5.5+
  • 伪类选择器(9):
    • :nth-child(an + b):伪类,选择前面有 an + b - 1 个兄弟节点的元素,其中 n >= 0, 兼容性 IE9+
    • :nth-last-child(an + b):伪类,选择后面有 an + b - 1 个兄弟节点的元素 其中 n >= 0,兼容性 IE9+
    • X:nth-of-type(an+b):伪类,X 为选择器,解析得到元素标签,选择前面有 an + b - 1 个相同标签兄弟节点- 兼容性 IE9+
    • X:nth-last-of-type(an+b):伪类,X 为选择器,解析得到元素标签,选择后面有 an+b-1 个相同标签兄弟- 素。兼容性 IE9+
    • X:first-child:伪类,选择满足 X 选择器的元素,且这个元素是其父节点的第一个子元素。兼容性 IE7+
    • X:last-child:伪类,选择满足 X 选择器的元素,且这个元素是其父节点的最后一个子元素。兼容性 IE9+
    • X:only-child:伪类,选择满足 X 选择器的元素,且这个元素是其父元素的唯一子元素。兼容性 IE9+
    • X:only-of-type:伪类,选择 X 选择的元素,解析得到元素标签,如果该元素没有相同类型的兄弟节点时选中- 性 IE9+
    • X:first-of-type:伪类,选择 X 选择的元素,解析得到元素标签,如果该元素 是此此类型元素的第一个兄- 它。兼容性 IE9+

JS-闭包

不会被销毁的作用域就是闭包,例如全局作用域.

闭包创建于函数声明时,函数无论怎么调用,作用域内部都可以访问声明时自身作用域内部和外部的所有变量.

创建闭包 - 作为返回值

var name = "global";

// 作为返回值产生闭包
function closure1() {
    var name = "closure1";

    // 这里是 closure 上下文区域
    function fn() {
        // 这里保存了对 closure 闭包作用域的访问权限
        console.log(name);
    }

    // 函数作为返回值
    return fn;
}
var test1 = closure1();
test1(); // closure1

console.log(name); // global
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

创建闭包 - 作为值

var name = "global";
// 作为参数产生闭包
var test2;

function closure2() {
    var name = "closure2";

    // 这里是 closure 上下文区域
    function fn() {
        // 这里保存了对 closure 闭包作用域的访问权限
        console.log(name);
    }

    // 函数作为参数
    test2 = fn;
}

closure2();
test2(); // closure2

console.log(name); // global
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

作为参数

var name = "global";

function foo(callback) {
    var name = "foo";
    callback(); // 函数在这里调用,但并不从 close 函数访问 name
}

// closure 函数在这里声明, 并创建闭包 或者 直接使用全局闭包
function closure() {
    console.log(name);
}

foo(next); //global
1
2
3
4
5
6
7
8
9
10
11
12
13

闭包的使用

保护私有变量,不可以直接访问

function Closure() {
    var num = 1;
    this.add = function () {
        num++;
    };
    this.getNum = function () {
        return num;
    };
}

var fn = new Closure();

console.log(fn.getNum()); // 1
fn.add();
console.log(fn.getNum()); // 2
console.log("fn.num 是否可以访问", typeof fn.num); // undefined
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

回调函数与计时器

var callback = function () {
    console.log(i);
};

for (var i = 0; i < 5; i++) {
    setTimeout(callback, 1000);
}
// for 循环函数会被 JS 引擎预解析成
var i = 0;
setTimeout(callback, 1000);
i++;
setTimeout(callback, 1000);
i++;
setTimeout(callback, 1000);
i++;
setTimeout(callback, 1000);
i++;
setTimeout(callback, 1000);
i++;
// 在执行就是等待 1000ms 后直接输出 5 5 5 5 5

// 修改 使用立即执行函数 IIFE,传参
// IIFE 会将基本类型参数拷贝一份存储
// 下面代码 1000ms 后输出 0 1 2 3 4

for (var i = 0; i < 5; i++) {
    (function (i) {
        setTimeout(function () {
            console.log(i);
        }, 1000);
    })(i);
}

// 修改用i * 时间,完成计时器
// 下面代码每隔 1000ms 后依次输出 0 1 2 3 4
for (var i = 0; i < 5; i++) {
    (function (i) {
        setTimeout(function () {
            console.log(i);
        }, 1000 * i);
    })(i);
}
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

JS-费波纳茨数列

费波纳茨数列又称黄金分割数列或者兔子数列,从第 3 项开始,每一项都等于前两项之和;而且当 n 趋向于无穷大时,前一项与后一项的比值越来越逼近黄金分割 0.618,所以极限是黄金分割比;从第二项开始,每个偶数项的平方都比前后两项之积少 1,每个奇数项的平方都比前后两项之积多 1。下面主要介绍费波纳茨数列 JS 实现。

求费波纳茨数列第 N 位的数值

递归实现

const fibonacci = (n, arr = [1, 2]) => {
    return (function loop(len) {
        if (len < n) {
            arr.push(arr[len - 1] + arr[len - 2]);
            return loop(arr.length);
        } else return arr[len - 1];
    })(arr.length);
};
console.log(fibonacci(1475));
// 输出 1.3069892237633987e+308
// 耗时 9.923828125ms
// 注意 第 1476 项数值为 Infinity
1
2
3
4
5
6
7
8
9
10
11
12

循环实现

const fibonacci = (n, arr = [1, 2]) => {
    for (let i = 2; i < n; i++) {
        arr[i] = arr[i - 1] + arr[i - 2];
    }
    return arr[n - 1];
};
console.log(fibonacci(1475));

// 输出 1.3069892237633987e+308
// 耗时 10.2490234375ms
// 注意 第 1476 项数值为 Infinity
1
2
3
4
5
6
7
8
9
10
11

拓展:求和 + 阶乘

// 求和
const loop = (n) => (n > 1 ? n + loop(--n) : n);
console.log(loop(1)); // 1
console.log(loop(3)); // 6
console.log(loop(5)); // 15

// 阶乘
const loop = (n) => (n > 1 ? n * loop(--n) : n);
console.log(loop(1)); // 1
console.log(loop(3)); // 6
console.log(loop(5)); // 120
1
2
3
4
5
6
7
8
9
10
11

拓展:尾调用优化

尾调用(Tail Call)是函数式编程的一个重要概念,本身非常简单,一句话就能说清楚,就是指某个函数的最后一步是调用另一个函数(仅函数调用,带函数的表达式运算不是尾调用);

函数调用会在内存形成一个“调用记录”,又称“调用帧”(call frame),保存调用位置和内部变量等信息。如果在函数 A 的内部调用函数 B,那么在 A 的调用帧上方,还会形成一个 B 的调用帧。等到 B 运行结束,将结果返回到 A,B 的调用帧才会消失。如果函数 B 内部还调用函数 C,那就还有一个 C 的调用帧,以此类推。所有的调用帧,就形成一个“调用栈”(call stack)。

尾调用由于是函数的最后一步操作,所以不需要保留外层函数的调用帧,因为调用位置、内部变量等信息都不会再用到了,只要直接用内层函数的调用帧,取代外层函数的调用帧就可以了。

这就叫做“尾调用优化”(Tail call optimization),即只保留内层函数的调用帧。如果所有函数都是尾调用,那么完全可以做到每次执行时,调用帧只有一项,这将大大节省内存。这就是“尾调用优化”的意义。

注意,只有不再用到外层函数的内部变量,内层函数的调用帧才会取代外层函数的调用帧,否则就无法进行“尾调用优化”。

// 不属于
function f(x) {
    let y = g(x);
    return y;
}

// 不属于
function f(x) {
    return g(x) + 1;
}

// 不属于
function f(x) {
    g(x);
}

// 属于,尾调用不一定出现在函数尾部,只要是最后一步操作即可。
function f(x) {
    if (x > 0) {
        return m(x);
    }
    return n(x);
}

// 函数不会进行尾调用优化,因为内层函数inner用到了外层函数addOne的内部变量one。
function addOne(a) {
    var one = 1;
    function inner(b) {
        return b + one;
    }
    return inner(a);
}

// 函数调用自身,称为递归。如果尾调用自身,就称为尾递归。

// 不会尾调用优化,堆栈溢出
function factorial(n) {
    if (n === 1) return 1;
    return n * factorial(n - 1);
}
factorial(5); // 120

// 会尾调用优化,堆栈不溢出
function factorial(n, total) {
    if (n === 1) return total;
    return factorial(n - 1, n * total);
}
factorial(5, 1); // 120

// 不会尾调用优化,堆栈溢出
function Fibonacci(n) {
    if (n <= 1) {
        return 1;
    }

    return Fibonacci(n - 1) + Fibonacci(n - 2);
}

// 会尾调用优化,堆栈不溢出
function Fibonacci2(n, ac1 = 1, ac2 = 1) {
    if (n <= 1) {
        return ac2;
    }
    return Fibonacci2(n - 1, ac2, ac1 + ac2);
}
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
57
58
59
60
61
62
63
64
65

由此可见,“尾调用优化”对递归操作意义重大,所以一些函数式编程语言将其写入了语言规格。ES6 亦是如此,第一次明确规定,所有 ECMAScript 的实现,都必须部署“尾调用优化”。这就是说,ES6 中只要使用尾递归,就不会发生栈溢出,相对节省内存。

尾递归的实现,往往需要改写递归函数,确保最后一步只调用自身。做到这一点的方法,就是把所有用到的内部变量改写成函数的参数。

CSS-未整理内容

选择器

常用(6):
    * 通用选择器 :选择所有元素,不参与计算优先级,兼容性IE6+
    #X id选择器:选择id值为X的元素,兼容性:IE6+
    .X 类选择器: 选择class包含X的元素,兼容性:IE6+
    X Y后代选择器: 选择满足X选择器的后代节点中满足Y选择器的元素,兼容性:IE6+
    X 元素选择器: 选择标所有签为X的元素,兼容性:IE6+
    :link,:visited,:focus,:hover,:active链接状态: 选择特定状态的链接元素,顺序LoVe HAte- : IE4+

兄弟选择器(3):
    X + Y直接兄弟选择器:在X之后第一个兄弟节点中选择满足Y选择器的元素,兼容性: IE7+
    X > Y子选择器: 选择X的子元素中满足Y选择器的元素,兼容性: IE7+
    X ~ Y兄弟: 选择X之后所有兄弟节点中满足Y选择器的元素,兼容性: IE7+

属性选择器(8):
    [attr]:选择所有设置了attr属性的元素,兼容性IE7+
    [attr=value]:选择属性值刚好为value的元素
    [attr~=value]:选择属性值为空白符分隔,其中一个的值刚好是value的元素
    [attr|=value]:选择属性值刚好为value或者value-开头的元素
    [attr^=value]:选择属性值以value开头的元素
    [attr$=value]:选择属性值以value结尾的元素
    [attr=value]*:选择属性值中包含value的元素
    [:checked]:选择单选框,复选框,下拉框中选中状态下的元素,兼容性:IE9+

伪元素选择器(5):
    X:after, X::after:after伪元素,选择元素虚拟子元素(元素的最后一个子元素),CSS3中::表示伪元素,:after为IE8+,::after为IE9+
    :hover:鼠标移入状态的元素,兼容性a标签IE4+, 所有元素IE7+
    :not(selector):选择不符合selector的元素。不参与计算优先级,兼容性:IE9+
    ::first-letter:伪元素,选择块元素第一行的第一个字母,兼容性IE5.5+
    ::first-line:伪元素,选择块元素的第一行,兼容性IE5.5+

伪类选择器(9):
    :nth-child(an + b):伪类,选择前面有an + b - 1个兄弟节点的元素,其中n >= 0, 兼容性IE9+
    :nth-last-child(an + b):伪类,选择后面有an + b - 1个兄弟节点的元素 其中n >= 0,兼容性IE9+
    X:nth-of-type(an+b):伪类,X为选择器,解析得到元素标签,选择前面有an + b - 1个相同标签兄弟节点- 兼容性IE9+
    X:nth-last-of-type(an+b):伪类,X为选择器,解析得到元素标签,选择后面有an+b-1个相同标签兄弟- 素。兼容性IE9+
    X:first-child:伪类,选择满足X选择器的元素,且这个元素是其父节点的第一个子元素。兼容性IE7+
    X:last-child:伪类,选择满足X选择器的元素,且这个元素是其父节点的最后一个子元素。兼容性IE9+
    X:only-child:伪类,选择满足X选择器的元素,且这个元素是其父元素的唯一子元素。兼容性IE9+
    X:only-of-type:伪类,选择X选择的元素,解析得到元素标签,如果该元素没有相同类型的兄弟节点时选中- 性IE9+
    X:first-of-type:伪类,选择X选择的元素,解析得到元素标签,如果该元素 是此此类型元素的第一个兄- 它。兼容性IE9+
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

精灵图 Sprite

将多个小图片拼接到一个图片中。通过 background-position 和元素尺寸调节需要显示的背景图案。

优点:

  • 减少 HTTP 请求数,极大地提高页面加载速度
  • 增加图片信息重复度,提高压缩比,减少图片大小
  • 更换风格方便,只需在一张或几张图片上修改颜色或样式即可实现

缺点:

  • 图片合并麻烦
  • 维护麻烦,修改一个图片可能需要从新布局整个图片,样式

推荐使用阿里巴巴矢量图标库

display & visibility

  • 联系:它们都能让元素不可见
  • 区别:
    • display:none;会让元素完全从渲染树中消失,渲染的时候不占据任何空间;visibility: hidden;不会让元素从渲染树消失,渲染师元素继续占据空间,只是内容不可见
    • display: none;是非继承属性,子孙节点消失由于元素从渲染树消失造成,通过修改子孙节点属性无法显示;visibility: hidden;是继承属性,子孙节点消失由于继承了 hidden,通过设置 visibility: visible;可以让子孙节点显式
    • 修改常规流中元素的 display 通常会造成文档重排。修改 visibility 属性只会造成本元素的重绘。
    • 读屏器不会读取 display: none;元素内容;会读取 visibility: hidden;元素内容

block & inline

  • block 元素特点:

    1. 处于常规流中时,如果 width 没有设置,会自动填充满父容器
    2. 可以应用 margin/padding
    3. 在没有设置高度的情况下会扩展高度以包含常规流中的子元素
    4. 处于常规流中时布局时在前后元素位置之间(独占一个水平空间) 5.忽略 vertical-align
  • inline 元素特点

    1. 水平方向上根据 direction 依次布局
    2. 不会在元素前后进行换行
    3. 受 white-space 控制
    4. margin/padding 在竖直方向上无效,水平方向上有效
    5. width/height 属性对非替换行内元素无效,宽度由元素内容决定
    6. 非替换行内元素的行框高由 line-height 确定,替换行内元素的行框高由 height,margin,padding,border 决定 6.浮动或绝对定位时会转换为 block
    7. vertical-align 属性生效

CSS hack

利用不同浏览器对 CSS 的支持和解析结果不一样编写针对特定浏览器样式。

常见的 hack 有 属性 hack 选择器 hack IE 条件注释

IE 条件注释:适用于[IE5, IE9]常见格式如下

<!--[if IE 6]> <style></style> <![endif]-->
1

选择器 hack:不同浏览器对选择器的支持不一样

/***** Selector Hacks ******/

/* IE6 and below */
* html #uno {
    color: red;
}
/* IE7 */
*:first-child + html #dos {
    color: red;
}
/* IE7, FF, Saf, Opera  */
html > body #tres {
    color: red;
}
/* IE8, FF, Saf, Opera (Everything but IE 6,7) */
html>/**/body #cuatro {
    color: red;
}
/* Opera 9.27 and below, safari 2 */
html:first-child #cinco {
    color: red;
}
/* Safari 2-3 */
html[xmlns*=""] body:last-child #seis {
    color: red;
}
/* safari 3+, chrome 1+, opera9+, ff 3.5+ */
body:nth-of-type(1) #siete {
    color: red;
}
/* safari 3+, chrome 1+, opera9+, ff 3.5+ */
body:first-of-type #ocho {
    color: red;
}
/* saf3+, chrome1+ */
@media screen and (-webkit-min-device-pixel-ratio: 0) {
    #diez {
        color: red;
    }
}
/* iPhone / mobile webkit */
@media screen and (max-device-width: 480px) {
    #veintiseis {
        color: red;
    }
}
/* Safari 2 - 3.1 */
html[xmlns*=""]:root #trece {
    color: red;
}
/* Safari 2 - 3.1, Opera 9.25 */
*|html[xmlns*=""] #catorce {
    color: red;
}
/* Everything but IE6-8 */
:root * > #quince {
    color: red;
}
/* IE7 */
* + html #dieciocho {
    color: red;
}
/* Firefox only. 1+ */
#veinticuatro,
x:-moz-any-link {
    color: red;
}
/* Firefox 3.0+ */
#veinticinco,
x:-moz-any-link,
x:default {
    color: red;
}
属性hack:不同浏览器解析bug或方法
/* IE6 */
#once {
    _color: blue;
}
/* IE6, IE7 */
#doce {
    *color: blue; /* or #color: blue */
}
/* Everything but IE6 */
#diecisiete {
    color/**/: blue;
}
/* IE6, IE7, IE8 */
#diecinueve {
    color: blue\9;
}
/* IE7, IE8 */
#veinte {
    color/*\**/: blue\9;
}
/* IE6, IE7 -- acts as an !important */
#veintesiete {
    color: blue !ie;
} /* string after ! can be anything */
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98

specified value & computed value & used value

  • specified value: 计算方法如下:

      如果样式表设置了一个值,使用这个值
      如果没有设置值,这个属性是继承属性,从父元素继承
      如果没设置,并且不是继承属性,使用css规范指定的初始值
    
  • computed value: 以 specified value 根据规范定义的行为进行计算,通常将相对值计算为绝对值,例如 em 根据 font-size 进行计算。一些使用百分数并且需要布局来决定最终值的属性,如 width,margin。百分数就直接作为 computed value。line-height 的无单位值也直接作为 computed value。这些值将在计算 used value 时得到绝对值。computed value 的主要作用是用于继承

  • used value:属性计算后的最终值,对于大多数属性可以通过 window.getComputedStyle 获得,尺寸值单位为像素。以下属性依赖于布局,

      background-position
      bottom, left, right, top
      height, width
      margin-bottom, margin-left, margin-right, margin-top
      min-height, min-width
      padding-bottom, padding-left, padding-right, padding-top
      text-indent
    
  • link 是 HTML 方式, @import 是 CSS 方式
  • link 最大限度支持并行下载,@import 过多嵌套导致串行下载,出现 FOUC 闪烁
  • link 可以通过 rel="alternate stylesheet"指定候选样式
  • 浏览器对 link 支持早于@import,可以使用@import 对老浏览器隐藏样式
  • @import 必须在样式规则之前,可以在 css 文件中引用其他文件
  • 总体来说:link 优于@import

CSS 继承属性

BFC

块级格式化上下文(block formatting context)

创建规则:

  • 根元素
  • 浮动元素(float 不是 none)
  • 绝对定位元素(position 取值为 absolute 或 fixed)
  • display 取值为 inline-block,table-cell, table-caption,flex, inline-flex 之一的元素
  • overflow 不是 visible 的元素

作用:

  • 可以包含浮动元素
  • 不被浮动元素覆盖
  • 阻止父子元素的 margin 折叠

外边距折叠

collapsing margins,毗邻的两个或多个 margin 会合并成一个 margin,叫做外边距折叠。

规则如下:

  • 两个或多个毗邻的普通流中的块元素垂直方向上的 margin 会折叠
  • 浮动元素/inline-block 元素/绝对定位元素的 margin 不会和垂直方向上的其他元素的 margin 折叠
  • 创建了块级格式化上下文的元素,不会和它的子元素发生 margin 折叠
  • 元素自身的 margin-bottom 和 margin-top 相邻时也会折叠

清理浮动

  • 容器元素闭合标签前添加额外元素并设置 clear: both
  • 父元素触发块级格式化上下文(见块级可视化上下文部分)
  • 设置容器元素伪元素进行清理推荐的清理浮动方法
/**
* 在标准浏览器下使用
* 1 content内容为空格用于修复opera下文档中出现
*   contenteditable属性时在清理浮动元素上下的空白
* 2 使用display:table而不是block:可以防止容器和
*   子元素top-margin折叠,这样能使清理效果与BFC,IE6/7 zoom: 1;一致
**/
.clearfix:before,
.clearfix:after {
    content: " "; /* 1 */
    display: table; /* 2 */
}

.clearfix:after {
    clear: both;
}
/* IE 6/7触发hasLayout实现包含浮动 */
.clearfix {
    *zoom: 1;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

HTML - 基础篇

Doctype 作用? 严格模式与混杂模式如何区分?它们有何意义?

  • 声明位于文档中的最前面,处于 标签之前。告知浏览器以何种模式来渲染文档。

  • 严格模式的排版和 JS 运作模式是,以该浏览器支持的最高标准运行。

  • 在混杂模式中,页面以宽松的向后兼容的方式显示。模拟老式浏览器的行为以防止站点无法工作。

  • DOCTYPE 不存在或格式不正确会导致文档以混杂模式呈现。

兼容模式 & 标准模式

  • 标准模式的排版和 JS 运作模式都是以该浏览器支持的最高标准运行;兼容模式中页面以宽松的向后兼容的方式显示来模拟老式浏览器的行为以防止站点无法工作.
  • 在标准模式中:内容宽度 = width; 在兼容模式中 :内容宽度 = width-2border-2padding
  • 在标准模式中:行内元素设置宽高无效,在兼容模式中有效
  • 在标准模式中:margin:0 auto 设置水平居中有效,在兼容模式中无效(需使用 text-align)
  • 在兼容模式中图片的 padding 会失效,Table 中的字体属性不能继承上层的设置,white-space:pre 会失效

iframe 缺点

  • iframe 会阻塞主页面的 Onload 事件;
  • 搜索引擎的检索程序无法解读这种页面,不利于 SEO;
  • iframe 和主页面共享连接池,而浏览器对相同域的连接有限制,所以会影响页面的并行加载。
  • 如果需要使用 iframe,最好是通过 javascript 动态给 iframe 添加 src 属性值,这样可以绕开以上两个问题。

HTML 与 XHTML —— 二者有什么区别?

  • XHTML 元素必须被正确地嵌套。

  • XHTML 元素必须被关闭。

  • 标签名必须用小写字母。

  • XHTML 文档必须拥有根元素。

<img> 标签上 title 属性与 alt 属性的区别是什么?

  • alt 属性是为了给那些不能看到你文档中图像的浏览者提供文字说明的。且长度必须少于 100 个英文字符或者用户必须保证替换文字尽可能的短。

  • 这包括那些使用本来就不支持图像显示或者图像显示被关闭的浏览器的用户,视觉障碍的用户和使用屏幕阅读器的用户等。

  • title 属性为设置该属性的元素提供建议性的信息。使用 title 属性提供非本质的额外信息。参考《alt 和 title 属性的区别及应用》

简述一下 src 与 href 的区别

  • src 用于替换当前元素;href 用于在当前文档和引用资源之间确立联系。

  • src 是 source 的缩写,指向外部资源的位置,指向的内容将会嵌入到文档中当前标签所在位置

  • href 是 Hypertext Reference 的缩写,指向网络资源所在位置,建立和当前元素(锚点)或当前文档(链接)之间的链接

元素标签分类

标签语义化的理解?

  • 去掉或者丢失样式的时候能够让页面呈现出清晰的结构

  • 有利于 SEO:和搜索引擎建立良好沟通,有助于爬虫抓取更多的有效信息:爬虫依赖于标签来确定上下文和各个关键字的权重;

  • 方便其他设备解析(如屏幕阅读器、盲人阅读器、移动设备)以意义的方式来渲染网页;

  • 便于团队开发和维护,语义化更具可读性,遵循 W3C 标准的团队都遵循这个标准,可以减少差异化。

标签 介绍
header 代表“网页”或“section”的页眉,没有个数限制。
footer 代表“网页”或“section”的页脚,没有个数限制。通常含有该节的一些基本信息,譬如:作者,相关文档链接,版权资料。
hgroup 代表“网页”或“section”的标题和元数据组,该元素可以将 h1 到 h6 元素放在其内,譬如文章的主标题和副标题的组合
nav 页面的导航链接区域。用于定义页面的主要导航部分。推荐单个使用。
aside 包含在 article 元素中作为主要内容的附属信息部分,其中的内容可以是与当前文章有关的相关资料、标签、名次解释等。(特殊的 section),或者作为侧边栏广告,其他日志链接或者其他分类导航
section 文档中的“节”或“段”,“段”可以是指一篇文章里按照主题的分段;“节”可以是指一个页面里的分组。article、nav、aside 可以理解为特殊的 section,所以如果可以用 article、nav、aside 就不要用 section,没实际意义的就用 div。
article 代表一个在文档,页面或者网站中自成一体的内容,其目的是为了让开发者独立开发或重用。
address 作为联系信息出现,邮编地址、邮件地址等等,一般出现在 footer。
time 标记一篇

html5 有哪些新特性、移除了那些元素?

新特性:

  • HTML5 现在已经不是 SGML 的子集,主要是关于图像,位置,存储,多任务等功能的增加。

  • 拖拽释放(Drag and drop) API

  • 语义化标签(header,nav,footer,aside,article,section)

  • 音频、视频 API(audio,video)

  • 画布(Canvas) API

  • 地理(Geolocation) API

  • 本地离线存储 localStorage 长期存储数据,浏览器关闭后数据不丢失

  • sessionStorage 的数据在页面会话结束时会被清除

  • 表单控件,calendar、date、time、email、url、search

  • 新的技术 webworker, websocket 等

移除的元素:

  • 纯表现的元素:basefont,big,center, s,strike,tt,u;

  • 对可用性产生负面影响的元素:frame,frameset,noframes;

HTML5 的文件离线储存怎么使用,工作原理是什么?

在线情况下,浏览器发现 HTML 头部有 manifest 属性,它会请求 manifest 文件,如果是第一次访问,那么浏览器就会根据 manifest 文件的内容下载相应的资源,并进行离线存储。如果已经访问过并且资源已经离线存储了,那么浏览器就会使用离线的资源加载页面。然后浏览器会对比新的 manifest 文件与旧的 manifest 文件,如果文件没有发生改变,就不会做任何操作,如果文件改变了,那么就会重新下载文件中的资源,并且进行离线存储。例如,

在页面头部加入 manifest 属性

<html manifest="cache.manifest"></html>
1

在 cache.manifest 文件中编写离线存储的资源

CACHE MANIFEST
#v0.11
CACHE:
js/app.js
css/style.css

NETWORK:
Resourse/logo.png

FALLBACK:
 //offline.html
1
2
3
4
5
6
7
8
9
10
11
  1. CACHE:必选,表示需要离线存储的资源列表,由于包含 manifest 文件的页面将被自动离线存储,所以不需要把页面自身也列出来。
  2. NETWORK:可选,可以使用通配符,表示在它下面列出来的资源只有在在线的情况下才能访问,他们不会被离线存储,所以在离线情况下无法使用这些资源。不过,如果在 CACHE 和 NETWORK 中有一个相同的资源,那么这个资源还是会被离线存储,也就是说 CACHE 的优先级更高。
  3. FALLBACK:可选,表示如果访问第一个资源失败,那么就使用第二个资源来替换他,如/html/ /404.html 表示用 “404.html” 替代 /html/ 目录中的所有文件,/ /404.html 表示用 “404.html” 替代当前目录中的所有文件,*.html /404.html 表示用 “404.html” 替代 所有 html 文件。

注意 :manifest 文件最好不要设置缓存, manifest 文件和离线资源 要一起更新,如果某个资源由于某种原因下载失败,那么这次的所有更新就算是失败的,浏览器还是会使用原来的资源;在更新了资源之后,新的资源需要到下次再打开 app 才会生效,如果需要资源马上就能生效,那么可以使用 window.applicationCache.swapCache()方法来使之生效,出现这种现象的原因是浏览器会先使用离线资源加载页面,然后再去检查 manifest 是否有更新,所以需要到下次打开页面才能生效。

参考资料:https://developer.mozilla.org/zh-CN/docs/Web/Manifest

页面资源预加载(Link prefetch)是浏览器提供的一个技巧,目的是让浏览器在空闲时间下载或预读取一些文档资源,用户在将来将会访问这些资源。一个 Web 页面可以对浏览器设置一系列的预加载指示,当浏览器加载完当前页面后,它会在后台静悄悄的加载指定的文档,并把它们存储在缓存里。当用户访问到这些预加载的文档后,浏览器能快速的从缓存里提取给用户。

  • 为什么需要预加载?

用户可能是第一次访问网站或者清空了浏览器缓存,总之当前页面没缓存

用户可能要访问的下一个页面的资源,预先加载,秒打开体验更好

  • DNS prefetch 预解析

我们知道,当我们访问一个网站如 www.amazon.com 时,需要将这个域名先转化为对应的 IP 地址,这是一个非常耗时的过程。

DNS prefetch 分析这个页面需要的资源所在的域名,浏览器空闲时提前将这些域名转化为 IP 地址,真正请求资源时就避免了上述这个过程的时间。

<meta http-equiv='x-dns-prefetch-control' content='on'>
<link rel='dns-prefetch' href='http://g-ecx.images-amazon.com'>
<link rel='dns-prefetch' href='http://z-ecx.images-amazon.com'>
1
2
3
  • Resource prefetch 资源预加载

在 Chrome 下,我们可以用 link 标签声明特定文件的预加载:

<link rel='subresource' href='critical.js'>
<link rel='subresource' href='main.css'>

<link rel='prefetch' href='secondary.js'>

<!--在 Firefox 中或用 meta 标签声明:-->
<meta http-equiv="Link" content="<critical.js>; rel=prefetch">
1
2
3
4
5
6
7

rel='subresource' 表示当前页面必须加载的资源,应该放到页面最顶端先加载,有最高的优先级。

rel='prefetch' 表示当 subresource 所有资源都加载完后,开始预加载这里指定的资源,有最低的优先级。

注意:只有可缓存的资源才进行预加载,否则浪费资源!

  • Pre render 预渲染

预渲染提前加载好用户即将访问的下一个页面,慎用!

<link rel='prerender' href='http://www.pagetoprerender.com'>

<!--在 Firefox 中或用 rel='next' 来声明-->
<link rel="next" href="http://www.pagetoprerender.com">
1
2
3
4
  • 传递性:

    • cookie 为了标示用户身份而储存在用户本地终端(Client Side)上的数据(通常经过加密)。
    • cookie 数据始终在同源的 http 请求中携带(即使不需要),记会在浏览器和服务器间来回传递。
    • sessionStorage 和 localStorage 不会自动把数据发给服务器,仅在本地保存。
  • 存储大小:

    • cookie 数据大小不能超过 4k。
    • sessionStorage 和 localStorage 虽然也有存储大小的限制,但比 cookie 大得多,可以达到 5M 或更大。
  • 有期时间:

    • localStorage 存储持久数据,浏览器关闭后数据不丢失除非主动删除数据;
    • sessionStorage 数据在当前浏览器窗口关闭后自动删除。
    • cookie 设置的 cookie 过期时间之前一直有效,即使窗口或浏览器关闭

    日常问题

  • homebrew 运行报错:Version value must be a string; got a NilClass () (TypeError)

执行命令 brew update-reset
1
  • MAC 终端使用 clashX VPN 代理 ping 通 github 的方法
更改hosts
192.30.253.113 github.com
192.30.252.131 github.com
185.31.16.185 github.global.ssl.fastly.net
74.125.237.1 dl-ssl.google.com
173.194.127.200 groups.google.com
192.30.252.131 github.com
185.31.16.185 github.global.ssl.fastly.net
74.125.128.95 ajax.googleapis.com
1
2
3
4
5
6
7
8
9
  • Vue: 初始化项目报错:TypeError: this.getOptions is not a function:vue-style-loader
解决办法:

安装sass-loader@10.1.1 即可

注意不要安装sass-loader@11.0.0及以上

npm install sass-loader@10.1.1 --save
1
2
3
4
5
6
7

其他知识点

渐进增强

渐进增强是指在 web 设计时强调可访问性、语义化 HTML 标签、外部样式表和脚本。保证所有人都能访问页面的基本内容和功能同时为高级浏览器和高带宽用户提供更好的用户体验。核心原则如下:

  • 所有浏览器都必须能访问基本内容
  • 所有浏览器都必须能使用基本功能
  • 所有内容都包含在语义化标签中
  • 通过外部 CSS 提供增强的布局
  • 通过非侵入式、外部 javascript 提供增强功能
  • end-user web browser preferences are respected

PNG & GIF & JPG

  • GIF:
    • 8 位像素,256 色
    • 无损压缩
    • 支持简单动画
    • 支持 boolean 透明
    • 适合简单动画
  • JPEG:
    • 颜色限于 256
    • 有损压缩
    • 可控制压缩质量
    • 不支持透明
    • 适合照片
  • PNG:
    • 有 PNG8 和 truecolor PNG
    • PNG8 类似 GIF 颜色上限为 256,文件小,支持 alpha 透明度,无动画
    • 适合图标、背景、按钮

IE6 兼容

  • IE6 不支持 min-height,解决办法使用 css hack:
.target {
	min-height: 100px;
	height: auto !important;
	height: 100px; /*IE6下内容高度超过会自动扩展高度 */
}
1
2
3
4
5
  • olli的序号全为 1,不递增。解决方法:为 li 设置样式display: list-item;
  • 未定位父元素overflow: auto;,包含position: relative;子元素,子元素高于父元素时会溢出。解决办法:
  子元素去掉 position: relative; ;
  不能为子元素去掉定位时,父元素 position: relative;
1
2
  • IE6 只支持a标签的:hover伪类,解决方法:使用 js 为元素监听 mouseenter,mouseleave 事件,添加类实现效果:
  • IE5-8 不支持opacity,解决办法:
.opacity {
	opacity: 0.4;
	filter: alpha(opacity=60); /* for IE5-7 */
	-ms-filter: 'progid:DXImageTransform.Microsoft.Alpha(Opacity=60)'; /* for IE 8*/
}
1
2
3
4
5
  • IE6 在设置height小于font-size时高度值为font-size,解决办法:font-size: 0;
  • IE6 不支持 PNG 透明背景,解决办法: IE6 下使用 gif 图片
  • IE6-7 不支持display: inline-block解决办法:设置 inline 并触发 hasLayout
.class {
	display: inline-block;
	*display: inline;
	*zoom: 1;
}
1
2
3
4
5
  • IE6 下浮动元素在浮动方向上与父元素边界接触元素的外边距会加倍。解决办法:
    使用 padding 控制间距。
    浮动元素 `display: inline;`(css 标准规定浮动元素 display:inline 会自动调整为 block)
1
2
  • 通过为块级元素设置宽度和左右 margin 为 auto 时,IE6 不能实现水平居中,解决方法:
    为父元素设置`text-align: center;`
1

什么是 FOUC?如何避免

Flash Of Unstyled Content:用户定义样式表加载之前浏览器使用默认样式显示文档,用户样式加载渲染之后再从新显示文档,造成页面闪烁。解决方法:把样式表放到文档的 head

网站优化

内容优化

  • 减少 HTTP 请求:合并文件、CSS 精灵、inline Image
  • 减少 DNS 查询:DNS 查询完成之前浏览器不能从这个主机下载任何任何文件。方法:- DNS 缓存、将资源分布到恰当数量的主机名,平衡并行下载和 DNS 查询
  • 避免重定向:多余的中间访问
  • 使 Ajax 可缓存
  • 非必须组件延迟加载
  • 未来所需组件预加载
  • 减少 DOM 元素数量
  • 将资源放到不同的域下:浏览器同时从一个域下载资源的数目有限,增加域可以提高- 并行下载量
  • 减少 iframe 数量
  • 不要 404

Server 优化

  • 使用 CDN
  • 添加 Expires 或者 Cache-Control 响应头
  • 对组件使用 Gzip 压缩
  • 配置 ETag
  • Flush Buffer Early
  • Ajax 使用 GET 进行请求
  • 避免空 src 的 img 标签
  • 减小 cookie 大小
  • 引入资源的域名不要包含 cookie

CSS 优化

  • 将样式表放到页面顶部
  • 不使用 CSS 表达式
  • 不使用@import
  • 不使用 IE 的 Filter

JavaScript 优化

  • 将脚本放到页面底部
  • 将 javascript 和 css 从外部引入
  • 压缩 javascript 和 css
  • 删除不需要的脚本
  • 减少 DOM 访问
  • 合理设计事件监听器

Image 优化

  • 优化图片:根据实际颜色需要选择色深、压缩
  • 优化 css 精灵
  • 不要在 HTML 中拉伸图片
  • 保证 favicon.ico 小并且可缓存