- BFC(块格式化上下文)
- 首页白屏
- 函数柯里化
- bind、apply、call
- 如果阻塞了JS中的主线程会发生什么情况
- 浏览器和Node 事件循环机制区别
BFC(块格式化上下文)
常见的定位方案分为三种:普通流、浮动、绝对定位。
块格式化上下文(Block Formatting Context,BFC) 是Web页面的可视CSS渲染的一部分,是块盒子的布局过程发生的区域,也是浮动元素与其他元素交互的区域。而这里的 BFC
属于属于普通流,相当于具有 BFC
特性的元素可以看作一个独立的容器,无论容器内部的元素怎么调整,都不会影响到外部的元素。
下列情况会创建BFC:
- 根元素(
<html>
) - 浮动元素(元素的
float
不是none
) - 绝对定位元素(元素的
position
为absolute
或fixed
) - 行内块元素(元素的
display
为inline-block
) overflow
值不为visible
的块元素display
值为flow-root
的元素contain
值为layout
、content
或 paint 的元素- 弹性元素(
display
为flex
或inline-flex
元素的直接子元素) - 网格元素(
display
为grid
或inline-grid
元素的直接子元素) - …
案例
1 | <div style="border: 1px solid #000;"> |
这几行代码,如果直接运行会在网页上按照我们的预期显示出来两个色块,但仔细看下,会看出父元素的高度不正常,父元素看起来向空容器一样。原因在于子元素采用浮动,而浮动流不属于普通流,是独立定位的。
解决方法,按照上述规则,使用一个合适的方法,来进行创建BFC,从而告诉浏览器 ”我的最外层div需要创建BFC,按照常规方式渲染“
。
例如:在最外层 div
添加样式 float: left
(上述规则指出只要 float
不为 none
即可创建BFC ) , 当然如果觉得 float 不够优雅,还可以使用 overflow: hidden;
。(通常情况下,我们可能会使用伪元素添加 clear:both;
占位来清除浮动,从而使最外层 div 恢复正常)。
详情请看,请看阮老师的文章。
还有经典问题 margin
重叠问题
1 | <style> |
运行之后就会发现 两个 p标签 margin
发生重叠(同一个BFC内,两盒子垂直,就会发生 margin
塌陷重叠,而margin
值会以最大的为主。)
解决方法:
- 将 margin 换为 padding
- 利用
BFC
,在 p 外层添加个一层 div,并在新添加的元素上添加样式(overflow: hidden;),创建新的BFC,这样两个p标签不属于同一个BFC,则自然不会再发生 margin 重叠问题。
首页白屏
现在多数都使用的为Vue、React和Angular三大框架其中之一,但它们有个共同的特点,均为 JS 驱动,所以在 JS 解析前,网页处于空白页,什么都不显示,这就是我们所说的白屏。
解决方法
- SSR,服务端渲染,有明显的好处,对SEO友好,还可以加快网页打开速度。
- 预渲染,插件
prerender-spa-plugin
,编译阶段就将对应的页面渲染好,但是是没有数据的 - 骨架图,数据还未加载出来时,但会显示出网页的大致骨架,相对友好。
函数柯里化
柯里化,是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。
1 | function curry(fn) { |
bind、apply和call
func.bind(thisArg[, arg1[, arg2[, …]]])
调用函数后,返回绑定 this
之后的函数(以下为mdn文档中的案例),并不会执行
1 | const module = { |
func.apply(thisArg, [argsArray])
apply
接受一个参数数组 ,并会执行此函数,如果没有传递参数(或传入 null
、 undefined
)则默认指向 window
1 | const numbers = [5, 6, 2, 3, 7]; |
function.call(thisArg, arg1, arg2, …)
call
接受的是一个参数列表 ,并会执行此函数,如果没有传递参数(或传入 null
、 undefined
)则默认指向 window
1 | function Product(name, price) { |
如果阻塞了JS中的主线程会发生什么情况,就是下面的代码。
1 | setTimeout(() => console.log("hello world")) |
- 首先,执行第一行,将
setTimeout
添加到宏任务队列 - 其次,执行第二行,然后进入死循环,页面卡死
- 同步代码都没有执行完,自然是不会执行宏任务队列中的任务
浏览器和Node 事件循环机制区别
浏览器和Node 环境下,microtask 任务队列的执行时机不同
1 | function test () { |
Node完整循环机制
引用官方解释文字和图片
阶段概述
定时器:本阶段执行已经被 setTimeout() 和 setInterval() 的调度回调函数。
待定回调:执行延迟到下一个循环迭代的 I/O 回调。
idle, prepare:仅系统内部使用。
轮询:检索新的 I/O 事件;执行与 I/O 相关的回调(几乎所有情况下,除了关闭的回调函数,那些由计时器和 setImmediate() 调度的之外),其余情况 node 将在适当的时候在此阻塞。
检测:setImmediate() 回调函数在这里执行。
关闭的回调函数:一些关闭的回调函数,如:socket.on(‘close’, …)。
参考链接
BFC
https://developer.mozilla.org/zh-CN/docs/Web/Guide/CSS/Block_formatting_context
http://www.ruanyifeng.com/blog/2009/04/float_clearing.html
https://juejin.im/entry/59c3713a518825396f4f6969
面经
https://www.nowcoder.com/discuss/177482
浏览器和Node循环机制区别
https://github.com/Advanced-Frontend/Daily-Interview-Question/issues/26#issuecomment-469188501
https://juejin.im/post/5c337ae06fb9a049bc4cd218#heading-0
https://nodejs.org/zh-cn/docs/guides/event-loop-timers-and-nexttick/