前端知识点串讲-2

float 的理解

  • 在 CSS 中,任何元素都可以浮动。浮动元素会生成一个块级框,而不论它本身是何种元素。
  • CSS 属性将一个元素放在其容器的左边或右边,允许文本和内联元素环绕它。元素将从页面的正常流中删除,但仍然保留为流的一部分(与绝对定位相反)。
  • 如果浮动非替换元素,则要指定一个明确的宽度;否则,它们会尽可能地窄。
  • 假如在一行之上只有极少的空间可供浮动元素,那么这个元素会跳至下一行,这个过程会持续到某一行拥有足够的空间为止。

仍保留流的一部分怎么理解?

这里先解释下流的理解。首先流分为三种,标准文档流、文档流、文本流;

标准文档流 = 文档流 + 文本流

其实 float 的元素是从正常流中脱离的,说的是文档流,所以浮动元素会浮在正常流元素上面;仍然保留一部分说的文本流,正常流中的文本或内联元遇到浮动元素会换行。

实例

把 div3 的填充满内容,然后把 div2 的高度设置成小于 div3 ;可以看到 div2 是压在 div3 上面,这说明 float 元素是脱离文档流的,但是文本在遇到 float 元素时是换行显示的,并没有被 float 元素所遮挡,这就是文本流。

推荐阅读内容

CSS 盒模型

基本概念:标准模型+IE 模型

盒子模型就是块的组成部分,marginborderpaddingcontent
标准模型就是宽高只计算content,也就是content-box
IE模型就是宽高把borderpadding包含进来,注意不包含margin,也就是border-box

标准模型和 IE 模型的区别

区别就是上面说的宽高的计算方式不同。

CSS 如何设置这两种模型

1
2
box-sizing:content-box; // 标准模型,默认
box-sizing:border-box; // IE模型

JS 如何设置获取盒模对应的宽和高

1
2
3
4
5
6
7
8
9
10
11
// 这个只能获取内联样式的宽和高,也就是通过style属性设置的,不然即使css中设置了高度也获取不到
dom.style.width/height

// 这个是获取渲染后的宽和高,但是这个只有IE支持
dom.currentStyle.width/height

// 这个和上面一样,但是兼容所有主流浏览器------所以用这个
window.getComputedStyle(dom).width/height

// 这个也能获取渲染后的宽高,但是这个主要用于计算位置,因为返回值里面有位置和宽高信息
dom.getBoundingClientRect().width/height

根据盒模型解释边距重叠

BFC(边距重叠解决方案)

  1. BFC 的概念
    BFC 就是块级格式化上下文。
  2. BFC 的原理
    原理说白了就是渲染规则,规则是:
    1. BFC 这个元素的垂直方向的边距会发生重叠
    2. BFC 的区域不会与浮动元素的 box 重叠,这用来清除浮动和布局
      我们知道 float 的元素是覆盖在其他元素上面,比如 A,只是文本会受浮动元素影响,但是当把 A 设置成 BFC(overflow:hidden),float 元素就不会在 A 元素上面了。
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
  <style>
html * {
padding: 0;
margin: 0;
}
.parent {
background-color: red;
}
.child {
margin-top: 10px;
background-color: yellow;
height: 100px;
/* overflow: hidden; */
}
.float {
float: left;
height: 50px;
width: 200px;
background-color: blue;
}
</style>

<body>
<section class="parent" id="parent">
<div class="float"></div>
<article class="child"></article>
</section>
</body>
  1. BFC 在页面上是个独立的容器,外面的元素不会影响里面的元素,里面的也不会影响外面的
  2. 计算 BFC 高度时,浮动元素也会参与计算
    正常情况下,容器中有浮动元素,容器的高度是不受浮动元素影响,即使浮动元素独自占一行。但是如果容器设置成 BFC,高度就受浮动元素的影响了
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
  <style>
html * {
padding: 0;
margin: 0;
}
.parent {
background-color: red;
}
.child {
margin-top: 10px;
background-color: yellow;
height: 100px;
}
.float {
float: left;
height: 50px;
width: 200px;
background-color: blue;
}
</style>

<body>
<section class="parent" id="parent">
<article class="child"></article>
<div class="float"></div>
</section>
<script type="text/javascript">
window.onload = function() {
console.log(window.getComputedStyle(document.getElementById("parent")).height);
};
</script>
</body>

创建 BFC

  • 根元素(<html>)
  • 浮动元素(元素的 float 不是 none
  • 绝对定位元素(元素的 positionabsolutefixed
  • 行内块元素(元素的 displayinline-block
  • 表格单元格(元素的 displaytable-cell,HTML 表格单元格默认为该值)
  • 表格标题(元素的 displaytable-caption,HTML 表格标题默认为该值)
  • 匿名表格单元格元素(元素的 displaytable、``table-rowtable-row-group、``table-header-group、``table-footer-group(分别是 HTML table、row、tbody、thead、tfoot 的默认属性)或 inline-table
  • overflow 值不为 visible 的块元素
  • display 值为 flow-root 的元素

一篇不错的 BFC 的讲解,貌似和我听的一套课程

##DOM 事件类

DOM 事件的级别

1
2
3
4
5
DOM0 element.onclick=function(){} || <div onclick="clickme()"></div>

DOM2 element.addEventListener('click',function(){},false)

DOM3 element.addEventListener('keyup',function(){},false)

与其说是级别,不如说是版本。
DOM0 就是上面两种添加事件的时代。
DOM1 没有制定事件相关的内容
DOM2 就是增加了使用addEventListener添加事件的方式
DOM3 增加了很多的事件类型,比如鼠标事件、键盘事件等等

DOM 事件模型

说的就是冒泡和捕获

DOM 事件流

事件流分为三个阶段:
捕获阶段—目标阶段—冒泡阶段

描述 DOM 事件捕获的具体流程

window–document—html—body—继续向下到目标

注意第一个对象是 window,不是 html

EVent 对象的常见应用

1
2
3
4
5
event.preventDefault()
event.stopPropagation()
event.stopImmediatePropagation()
event.currentTarget // 绑定事件的元素
event.target // 触发事件的元素

前两个没啥可说的,直接说第三个;
比如给按钮绑定了两个事件eventAeventB,正常情况下,点击按钮后,eventAeventB都会被执行;
如果想执行eventA后不再执行eventB,在 eventA 中调用event.stopImmediatePropagation()就行了。
event.target 比较好理解,表示触发事件的元素。
event.currentTarget 表示绑定事件的元素;比如把事件绑定在父元素ul上,点击子元素li时,e.targetli,但是e.currentTargetul

自定义事件

1
2
3
4
5
6
// 定义事件
let eve=new Event('eventName')
// 绑定事件
dom.addEventListener('eventName',function(){})
// 触发事件
dom.dispatchEvent(eve)

如果定义事件时需要传递一些参数,可以使用CustomEvent

HTTP 协议类

主要特点

  • 简单快速
  • 灵活
  • 无连接
  • 无状态

HTTP 报文的组成部分

请求报文

  • 请求行
  • 请求头
  • 空行
  • 请求体

响应报文

  • 状态行
  • 响应行
  • 空行
  • 响应体

POST 和 GET 的区别

  1. GET 在浏览器回退时是无害的,而 POST 会再次提交请求 √
  2. GET 产生的 URL 地址可以被收藏,而 POST 不可用
  3. GET 请求会被浏览器主动缓存,而 POST 不会,除非手动设置 √
  4. GET 请求只能进行 url 编码,而 POST 支持多种编码方式
  5. GET 请求参数会被完整的保留在浏览器的历史记录里,而 POST 中的参数不会被保留 √
  6. GET 请求在 URL 中传送的参数是有长度限制的,而 POST 没有限制 √
  7. 对参数的数据类型,GET 只接受 ASCII 字符,而 POST 没有限制 √
  8. GET 比 POST 更不安全,因为参数直接暴露在 URL 上,所以不能用来传递敏感信息
  9. GET 参数通过 URL 传递,POST 放在 Request body 中

原型链类问题

创建对象有几种方法

总共三种

1
2
let o1 = { name:'zhangsan' } // 字面量的方式
let 02 = new Object({name:'zhagnsan'})

上面的两种写法是一种声明方式。

第二种:构造函数的方式

1
2
const Man = function() {};
let zhangsan = new Man();

第三种:Object.create()方法

1
2
let o1 = { name: "zhangsan" };
let o2 = Object.create(01);

1348523-c516f36ecb8241e3.png

原型、构造函数、实例、原型链

只要使用 new 创建实例,那这个函数这时就是构造函数,不使用 new 操作它,它就是普通的函数,所以任何函数都可以是构造函数。

使用实例原型链上的 constructor 和 function 进行对比,来判断实例是哪个 function 的实例。

手动实现 new 运算法

1
2
3
4
5
6
7
8
9
10
11
const Fun = function(func) {
// 首先创建一个空对象,并把它的原型指到func上
let o = Object.create(func.prototype);
// 执行原函数
let r = func.call(o);
// 判断原函数是否有返回值,有返回值则返回,没有则返回上面创造的对象
if (typeof r === "object") {
return r;
}
return o;
};

继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function Parent() {
this.name = "zhangsan";
this.list = [];
}
function Child() {
Parent.call(this);
this.age = 18;
}
// 第一种方式
Child.prototype = new Parent();
// 第二种方式
Child.prototype = Parent.prototype;
// 第三种方式
Child.prototype = Object.create(Parent.prototype);
Child.prototype.contructor = Child;
// 等同于
// Child.prototype.__proto__=Parent.prototype;

通信类

什么是同源策略及限制

同源策略限制从一个源加载的文档或脚本如何与来自另一个源的资源进行交互。
这是一个用于隔离潜在恶意文件的关键的安全机制。

源=协议+域名+端口

  • Cookie、LocalStorage 和 IndexDB 无法读取
  • DOM 无法获得
  • AJAX 请求不能发送

前后端如何通信

  • Ajax
  • WebSocket 不受同源策略限制
  • CORS 支持跨域通信也支持同源通信
    这是一个新的企业通信标准

如何创建一个 Ajax

  • XMLHttpRequest 对象的工作流程
  • 兼容性处理
  • 事件的触发条件
  • 事件的触发顺序

跨域通信的几种方式

  • jSONP
    使用 script 标签的 src 属性实现
  • Hash
    就是 url 中#号后面的内容,hash 的改变是不刷新页面的,query 是的改变会刷新(?后面的),所以 query 不能做
    跨域通信
1
2
3
4
5
6
7
8
9
10
// 场景是当前页面 A 通过 iframe或frame嵌入了跨域的页面 B
// 在 A 中的伪代码如下:
let B = document.getElementByTagName("iframe");
B[0].src = B[0].src + "#" + "data";

// 在 B 中的伪代码如下
window.onhashchange = function() {
let data = window.location.hash;
// 然后再用data发出请求
};

我想了想为什么 query 不行,按说上面的方式也能改变 url 的参数,并且在 B 页面是可以获取到的。但是为什么不能做跨域呢?
上面也说了这种方式不能是因为会引起刷新,问题是为什么引起刷新就不能做跨域了?
原因为刷新导致了其他服务端请求,这些请求被认为是 A 发出的,但是经过测试发现,iframe中发出的请求originreferer都是 B 自己。那应该也可以啊???

  • postMessage HTML5
  • WebSocket
  • CORS
    为什么 cors 能跨域?
    当浏览器发现发出的请求是 CORS,会在请求头里面加上 origin 参数。

安全类

主要就是 XSS 和 CSRF
https://segmentfault.com/n/1330000017762196?token=3c334f35a69008d4e1607e3530f1612f

算法类

  • 排序
    各种排序算法的复杂度

  • 堆栈、队列、链表

  • 递归

  • 波兰式和逆波兰式

Javascript 算法——快速排序

Javascript 算法——选择排序

Javascript 算法——希尔排序

JavaScript 中的递归

波兰式、逆波兰式与表达式求值

https://github.com/Tairraos/rpn.js/blob/master/rpn.js

文章作者: wenmu
文章链接: http://blog.wangpengpeng.site/2020/01/09/%E5%89%8D%E7%AB%AF%E7%9F%A5%E8%AF%86%E7%82%B9%E4%B8%B2%E8%AE%B2-2/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 温木的博客
微信打赏