一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第3天,点击查看活动详情。
一、grid的使用
1、grid跟flex的比较
grid 可以看作是二维的布局,flex是一维的布局
2、grid的属性
grid-template-columns和grid-template-rows: 定义行列的宽度,宽高的设置可使用px/%/repeat()/auto-fill关键字/fr关键字/minmax()函数/auto关键字,使用案例有:
// 表示每列宽度100px,每行有3列
div{
display: grid;
grid-template-columns: 100px 100px 100px;
}
// 表示每行有4列,列宽度为20% 30% 20% 30%
div{
display: grid;
grid-template-columns: repeat(2, 20% 30%);
}
// 表示列宽100px,每行自动填充,填充不下换行
div{
display: grid;
grid-template-columns: repeat(auto-fill, 100px);
}
// 表示每行自动填充,填充不下换行,列宽度为100px 100px 200px …………
div{
display: grid;
grid-template-columns: repeat(auto-fill, 100px, 1fr, 2fr);
}
// 表示每行有两列,列宽为50%,且每列宽度不小于100px
div{
display: grid;
grid-template-columns: 1fr 1fr minmax(100px, 1fr);
}
// 表示每行有3列,列宽为100px 100px auto,第三列有浏览器自己决定长度
div{
display: grid;
grid-template-columns: 100px 1fr auto;
}
grid-row-gap、grid-column-gap和grid-gap属性:设置行/列间距
// 表示行间距=列间距=20px
div {
grid-gap: 20px; // grid-gap: <grid-row-gap> <grid-column-gap>,第二个值可省略
}
-
grid-template-areas属性:用于定义区域,网格线的命名会自动变成区域名-start,区域名-end -
grid-auto-flow属性:与flex-direction类似,设置子元素的排序顺序,值为row/column/row-dense/column-dense
-
row/column: 表示按行/列排布,排不下的换行/列排布 -
row-dense/column-dense: 表示按行/列紧凑排布,当下一个排不下时会去找下一个能排下的元素,直至换行/列
- 单元格内布局
取值:
center、start、end和stretch(拉伸,默认值)
justify-items: 单元格内的水平位置;align-items: 单元格内的垂直位置;place-items: <align-items> <justify-items>
- 整个内容区域布局
取值有
center、start、end、stretch、space-around、space-between和space-evenly
justify-content: 整个内容区域在容器中的水平位置;align-content: 垂直位置;place-content: <align-content> <justify-content>
7.常用的有以上,其余的…………………………好多属性,再写也记不住了~ 用到的时候再记吧。
二、history 和 hash的区别
这两种都可以实现客户端改变视图的同时,不向后端发出请求。
1、hash模式
- 通过在
URL锚点#后面拼接路由参数的方法,这种改变hash的方法不会引起浏览器重新加载页面 - 利用
window.onhashchange事件,监听hash的更改,从而加载对应的页面(window.location.hash.substr(1))
2、history模式
- 利用
H5History Interface中新增的pushState()和replaceState()方法,来记录历史路由栈 - 该模式下,一般刷新之后会报
404错误,需要后端ng的配置 pushState和replaceState方法,只能导致history对象变化,浏览器不会向后端发送请求,也不会触发popstate事件(popstate事件是在点击浏览器前进后退按钮之后触发执行的)history模式下的路由监听使用popstate事件来实现
三、Map数据结构和WeakMap数据结构
1、Map
Map结构是一种数组键值对格式,它跟对象明显不一样的点是,它不对值进行强制类型转换Map方法let map = new Map(): 实例化一个Map数据结构set():map.set('name', 'test')get():map.get('name')delete():map.delete('name')clear():map.clear()size:map.size // 获取长度- 遍历:
map.forEach((value, key, self) => {}) - Map转对象,通过
Object.fromEntries(map)方法
2、WeakMap
WeakMap方法:没有了Map的遍历、clear清除、获取长度size的方法,只保留了以下四个delete()set()get()has()
- 同
Map不同的一点,WeakMap只接受对象作为键值 WeakMap是弱引用(对对象的弱引用是指当该对象应该被GC(Garbage Collection垃圾回收机制)回收时不会阻止GC的回收行为):当外部的引用被删除后,WeakMap内部的引用会相应的被GC垃圾回收WeakMap的使用场景: 可用于写DOM节点的监听事件,当DOM节点被删除后,WeakMap中对于该DOM节点的引用也会被垃圾回收,不容易造成内存泄漏
四、Set和WeakSet
Set和WeakSet的区别同Map和WeakMap类似
1、Set:本身是一个构造函数,类似于数组,但是数组中的值是唯一、不重复的
Set方法add()delete()has()clear()sizekeys(): 键名的遍历器values(): 键值的遍历器entries(): 键值对的遍历器forEach(): 使用回调函数遍历每个成员
- 常用的使用场景:用于对数组的去重
let a = [1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,8,9,10,10,11];
let b = [2,3,4,5,3,2,1,32,2321,12121];
let set = new Set([...a, ...b])
// 输出set结果:Set(14) {1, 2, 3, 4, 5, …}
let array = Array.from(set)
// 输出array结果:(14) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 32, 2321, 12121]
2、WeakSet
WeakSet: 结构同Set类似,区别是其成员只能是对象,且为Set和WeakSet,成员随时会消失,因此不支持遍历
WeakSet方法,去除掉遍历方法以及size,只有以下3个方法add()delete()has()
WeakSet常用的使用场景:用于存储DOM节点,当节点被移除后,相应的WeakSet也会被垃圾回收,不容易造成内存泄漏
五、移动端布局
移动端布局下,meta标签的常用写法
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no"/>
移动端的布局方法,常见的有以下几种:
1、rem布局
rem 同 em的区别是:rem是相对根元素font-size来布局,而em是相对父元素
设计思路:
-
移动端屏幕尺寸规定为
750px,设计稿尺寸为750px -
若将屏幕宽度分出为
10份,每一份大小为750/10 = 75 -
html根元素font-size: 设备宽度/75 + 'px',handleFontSizeRoot() { let width = document.documentElement.offsetWidth / 75; document.documentElement.style.fontSize = width + 'px'; } -
css布局时写法上:750px === 75rem,100px === 10rem,12px === 1.2rem -
postcss:一种对css编译的工具,类似babel-loader,可安装postcss-pxtorem插件,将px转换成rem,该插件对于px的检测是区分大小写的(即,Px/PX/pX不会被转换成rem);(这个
loader先简单提下,后面会有说明,具体可看下postcss对scoped的转译)
2、@media媒体查询
@media媒体类型查询,媒体类型取值有以下4个
all所有设备print打印设备screen电脑屏幕、平板屏幕、移动端屏幕speech
@media关键字查询,常用关键字有以下几种:
max-width: 1000px查询匹配宽度小于1000pxmin-width: 750px查询撇皮=宽度大于750pxand与运算连接符only表示唯一not否运算连接符
@media可以用在link标签上,用于按需加载css资源<link rel="stylesheet" href="css/1.css" media="(max-width:750px)"/>
3、百分比
- 直接使用百分比来布局,该方法下图片布局比较混乱
4、vh和vw布局方法
- 使用过程中有问题:
IOS下,软键盘是叠在可视窗口上的- 安卓下,软键盘会撑开一定高度
六、postcss对scoped的转译
七、文档流
1、会脱离文档流的布局方式
float浮动absolute布局方式fixed布局方式: 主要用于贴靠浮动
2、清除浮动的方法
- 父元素设置宽高自动撑起
- 浮动元素下新增一个空的同级元素,设置清除浮动样式:
clear: both - 浮动元素的父元素设置伪类
::after::before从而清除浮动
八、width offsetWidth clientWidth scrollWidth innerWidth的区别
width: 可读写,通过style.width来修改之,返回带单位的字符串offsetWidth:只读属性,返回整数值,表示元素的实际宽度,offsetWidth = width + padding + borderclientWidth: 可视区域的宽度scrollWidth:实际内容的宽度innerWidth:window.innerWidth表示浏览器窗口的内部宽度
九、height offsetHeight clientHeight scrollHeight innerHeight的区别
同上一点类似
十、for of 跟 for in 遍历器的区别
1、for of
for(let i of arr)i为键值value- 可用于遍历字符串,遍历得到字符
- 无法直接遍历对象拿到键值,但可以通过
Object.valuesObject.keysObject.entries来实现遍历
2、for in
for(let i in arr)i为键名key- 可用于遍历字符串,遍历得到字符的索引值
- 可用于遍历对象,遍历得到对象的
key
十一、重绘和回流
回流一定会触发重绘,重绘不一定会触发回流;
回流的代价会高于重绘。
1、回流
引起场景:当有元素宽高、布局、显示或隐藏,或元素内部的文字结构发生变化时,会引起回流(重新构建页面)
- 添加、删除DOM元素
DOM元素发生位移DOM元素尺寸变化(包括borderpaddingwidthheight等DOM元素文本更改- 页面一开始渲染的时候
- 页面尺寸改变
JS中获取DOM的偏移量属性,如offsetWidthclientWidth(相关原因后面有写)
2、重绘
当元素宽高、布局、显影等都未有更改,只是改变了元素的外观风格时,会引起重绘
DOM元素样式更改(visibility、color、background-color等)input数据框的变化css伪类
3、优化重绘和回流
- 用
transform替换top、left、margin-top、margin-left这些位移属性 opacity和visibility
visibility会引起重绘但不会引起回流- 只用
opacity会引起回流 opacity与transform: translateZ/3d不会产生回流和重绘
- 不要用
js对dom元素设置样式等,直接用一个className - 避免频繁用
js获取dom的样式,如offsetWidth,clientWidth这些。浏览器有一个回流的缓冲机制,多个回流会保存在一个栈里面,当这个栈满了浏览器会一次性触发所有样式的更改切刷新这个栈。当获取dom的样式时,浏览器为了给到一个准确的答案会不停刷新这个缓冲栈,导致页面回流增加。 - 动画的速度按照业务需求定,必要时可以开启
GPU加速 - 给需要频繁重绘和回流的节点单独设置图层,可设置成
absolute、fixed等 - 避免频繁操作
DOM,可通过cloneNode赋值DOM节点出来,更改完成后再replaceChild
4、16ms优化
大多数设备的刷新频率是60次/s,即没渲染一次要在1000ms/60次=16.6ms内完成,超出这个时间,页面的渲染会出现卡顿现象,影响用户体验
浏览器渲染页面的过程大致如下::
- 解析
HTML,生成DOM树 - 解析
CSS,生成CSSOM树 - 将
DOM树和CSSOM树结合,生成Render渲染树 Layout(回流)布局,根据窜蚺属,确定DOM元素在屏幕上显示的大小和位置Paint(重绘) 绘制DOM元素文字、颜色、图像、边框和阴影等Composite渲染层合并,按照合理的顺序合并图层然后显示到屏幕上
十二、关于线上环境bug的及时跟进
**sentry错误日志监控**: 主要用于vue项目发生产之后的bug收集;
目前开发的时候我们可调试,但一旦发生产之后,若出现bug,开发人员没办法及时获取到bug复现场景,只能依靠用户的反馈,这点很不友好,所以引入sentry错误日志监控,至于搭建流程,具体可看下官网(外国网站,国内浏览很慢~需要VPN)
十三、防抖和节流
1、防抖:
- 原理:事件触发后,延迟
n秒再执行,n秒内重复触发,则重新设置定时器计时 - 实现方法:
- 触发事件,清除定时器
- 设置定时器
n秒后执行
- 应用场景:
input框边输入边调用接口搜索
2、节流:
- 原理:某个时间段内只触发一次事件(即使多次点击)
- 实现方法:
- 判断
flag为true时,进入事件 - 事件中 置
flag为false, 设置定时器 - 定时器执行完成后,置
flag为true
- 应用场景:
button多次触发- 懒加载监听滚动条位置
十四、Promise的异常捕获如何实现
先不做说明,这个关于Promise的实现原理,下次补上
十五、webpack打包的步骤
具体可看下这两篇:
十六、webpack import原理
还在了解中,后面补充进来
十七、Vue3新出的composition API 跟 原本的option API有什么区别
首先,这两个的使用是不冲突的,需要使用哪个可供开发者自由选择。
十八、setTimeout跟Promise的执行顺序
这个问题是关于浏览器 JS引擎线程的事件循环机制,具体可看下我之前的文章