1.html语义化
要求使用具有语义的标签:header footer article aside section nav
三点好处:
(1)提高代码可读性,页面内容结构化,更清晰
(2)无css时,时页面呈现出良好的结构
(3)利于seo搜索,爬虫爬取有效信息
2.盒模型
边距边框填充实际内容 margin border padding content
W3c标准盒模型:默认,实际宽高包括padding和border box-sizing:content-box
ie怪异盒模型:实际宽高不包括padding border box-sizing:border-box
3.浮动
作用:常用于文字围绕图片
特点:脱离文档流,造成塌陷,影响其他元素排列
父元素高度塌陷解决:
- 父元素添加高度;
- 父元素overflow:hidden;
- 父元素添加after伪类;
.container::after{content: "";display: block;clear: both;}
- 在浮动子元素末尾创建一个空白div,添加clear:both;
.test{clear: both;}</style> </head> <body><div class="container"><div class="item"></div><div class="test"></div></div>
none,默认值,不清除浮动
left,清除左侧浮动元素对当前元素的影响
right,清除右侧浮动元素对当前元素的影响
both,清除两侧浮动元素对当前元素的影响,清除对他影响最大的那个元素的浮动
4.样式优先级
!important>行内样式>id选择器>类选择器>标签选择器(范围约小优先级越高)>通配符(*)
5.css尺寸设置的单位
Px绝对像素
Rem相对于根元素像素
Em相对于父元素
Vw/vh视口宽高
6.BFC
块级格式上下文。是一个独立的容器,内部元素和外部元素互不影响
条件:【什么情况下可以让元素产生BFC】
1、浮动元素:float属性不为none
2、绝对定位元素:position为absolute或fixed
3、display为inline-block、table-cell、table-caption、flex、inline-flex
4、overflow不为visible
【BFC元素具有的特性】
0、是一个独立的容器,内部元素和外部元素互不影响
1、在BFC中,盒子从顶部开始垂直地一个接一个排列
2、盒子垂直方向的距离由margin决定。同一个BFC的两个相邻盒子margin会重叠,并且取最大外边距。
3、BFC中,margin-left会触碰到border-left(对于从左至右的方式,反之)
4、BFC区域不会与浮动的盒子产生交集,而是紧贴边缘浮动
5、计算BFC高度时,自然会检测浮动的盒子高度
BFC应用场景
(1)父级元素没有高度时,子元素浮动导致父级元素高度塌陷问题。给父级元素添加overflow:hidden
(2)子元素外边距重叠导致父元素塌陷。添加overflow:hidden.(或者把子元素margin改成padding)
7.未知宽高元素水平垂直居中方法
(1)flex布局
父盒子开启flex弹性布局,设置justify-content: center;align-items: center;
<style>.container{display: flex;justify-content: center;align-items: center;width: 100%;height: 300px;background-color: yellow;}.item{width: 100px;height: 100px;background-color: green;}</style>
</head>
<body><div class="container"><div class="item"></div></div>
</body>
(2)绝对定位+位移+transform
子绝父相。子向右下移动父元素的一半,再利用transform.
top: 50%;left: 50%; transform: translate(-50%,-50%);
transform: translate(-50%, -50%);
:
translate
函数用于移动元素。负值表示向左(对于X轴)和向上(对于Y轴)移动。translate(-50%, -50%)
将元素向左移动其自身宽度的50%,并向上移动其自身高度的50%。
由于元素已经通过top
和left
属性定位到了其父元素的中心线(水平和垂直),这个transform
调用实际上是将元素的中心移动到这些中心线上,从而实现了真正的水平垂直居中。
.container{position: relative;width: 100%;height: 500px;background-color: yellow;}.item{position: absolute;top: 50%;left: 50%;transform: translate(-50%,-50%);width: 100px;height: 100px;background-color: green;}
(3)绝对定位+margin
子绝父相。设置子的top left bottom right都相等,margin设置为auto
.container{position: relative;width: 500px;height: 500px;background-color: yellow;}.item{position: absolute;top: 0;left: 0;right: 0;bottom: 0;margin: auto;width: 100px;height: 100px;background-color: green;}
(4)text-align
父盒子设置行高等于高,textaligncenter.
子盒子开启display:inline-block,设置vertical-align:middle.
.container{line-height: 500px;text-align: center;width: 500px;height: 500px;background-color: yellow;}.item{display: inline-block;vertical-align: middle;width: 100px;height: 100px;background-color: green;}
8.三栏布局
1.Flex布局:
左中右排列顺序。
父盒子dispaly:flex,左右设置固定大小宽高,中间盒子flex1。
flex: 1;
相当于以下三个属性的组合:
flex-grow: 1;
表示该弹性项会扩展以占用额外的空间(如果有的话)。所有设置了flex-grow
的弹性项会按照它们的flex-grow
值来分配容器中的额外空间。flex-shrink: 1;
表示该弹性项会缩小以适应容器。不过,在你给出的情境中,因为左右两边已经设置了固定的宽高,所以中间的弹性项通常不会因为flex-shrink
而缩小,除非容器的宽度小于左右两边宽度之和加上中间弹性项的最小内容宽度。flex-basis: 0%;
或flex-basis: auto;
(取决于浏览器默认设置)。flex-basis
定义了弹性项在主轴(默认是水平方向)上的初始大小。但在flex: 1;
的情况下,flex-basis
的具体值可能不会影响最终的布局,因为flex-grow
会扩展弹性项以占用剩余空间。
<style>.container{display: flex;
/* justify-content: space-between; */}.left{width: 200px;height: 200px;background-color: yellow;}.middle{flex: 1;/* height: 200px;*/background-color: green;}.right{width: 200px;height: 200px;background-color: blue;}</style>
</head>
<body><div class="container"><div class="left"></div><div class="middle"></div><div class="right"></div></div>
</body>
2.float浮动:
排列顺序:左右中。
左右设置固定大小和左右浮动,中间自适应overflow:hidden。(或者中间设置对应方向的margin值)
<style>.left{float: left;width: 200px;height: 200px;background-color: yellow;}.center{overflow: hidden;height: 200px;background-color: green;}.right{float: right;width: 200px;height: 200px;background-color: blue;}</style>
</head>
<body><div class="container"><div class="left"></div><div class="right"></div><div class="center"></div></div>
3.圣杯
中左右排列顺序。全部左浮动。左右盒子设置宽高,中间盒子设置宽度100%,父盒子设置左右内边距。左盒子设置 margin-left: -100%; position: relative; left: -300px; 右盒子设置margin-left: -200px; position: relative; right: -200px;
首先给这三个div都给一个float: left,让它们均左浮动。
设置左盒子的margin-left: -100%,把左盒子拉上来,调整左盒子的浮动位置到中间盒子的左侧。再设置右盒子的margin-left: - 右盒子宽度px,把右盒子拉上来,调整右盒子的浮动位置到中间盒子的右侧。
此时的布局基本出来了,但是中间盒子的左右两侧会被左右两个盒子覆盖掉,此时我们要通过相对定位来避免覆盖。给左右盒子position: relative,再分别设置它们的left和right,并且控制父元素的padding来为左右两边留白。
<style>*{margin: 0;padding: 0;}.container{padding-left: 300px;padding-right: 200px;height: 200px;}.middle{float: left;width: 100%;height: 200px;background-color: green;}.left{float: left;width: 300px;height: 200px;background-color: yellow;/* 左移 */margin-left: -100%;position: relative;left: -300px;}.right{float: left;width: 200px;height: 200px;background-color: blue;margin-left: -200px;position: relative;right: -200px;}</style>
</head>
<body><div class="container"><div class="middle"></div><div class="left"></div><div class="right"></div></div>
4.双飞翼
首先给这三个div都给一个float: left,让它们均左浮动。
设置左盒子的margin-left: -100%,把左盒子拉上来,调整左盒子的浮动位置到中间盒子的左侧。再设置右盒子的margin-left: - 右盒子宽度px,把右盒子拉上来,调整右盒子的浮动位置到中间盒子的右侧。
此时,在双飞翼布局中,避免左右盒子被覆盖是通过设置inner-middle的左右margin来实现的。
<style>*{margin: 0;padding: 0;}.middle{float: left;width: 100%;height: 200px;background-color: green;}.inner-middle{margin-left: 300px;margin-right: 200px;}.left{float: left;width: 300px;height: 200px;background-color: yellow;/* 左移 */margin-left: -100%;}.right{float: left;width: 200px;height: 200px;background-color: blue;margin-left: -200px;}</style>
</head>
<body><div class="container"><div class="middle"><div class="inner-middle"></div></div><div class="left"></div><div class="right"></div></div>
</body>
5.圣杯布局对比双飞翼布局
双飞翼布局好处
(1)主要的内容先加载的优化。
(2)兼容目前所有的主流浏览器,包括IE6在内。
(3)实现不同的布局方式,可以通过调整相关CSS属性即可实现。
对比
(1)都是左右栏定宽,中间栏自适应的三栏布局,中间栏都放到文档流前面,保证先行渲染。
(2)解决方案基本相似:都是三栏全部设置左浮动float:left,然后分别解决中间栏内容被覆盖的问题。
(3)解决中间栏内容被覆盖问题时,圣杯布局设置父元素的padding,双飞翼布局在中间栏嵌套一个div,内容放到新的div中,并设置margin,实际上,双飞翼布局就是圣杯布局的改进方案。
5.绝对定位布局 position+margin
排列顺序:左右中
子绝父相。左右两栏设置绝对定位,设置右栏的位置top right。中间设置对应方向的marginleft right值。
<style>*{margin: 0;padding: 0;}.container{position: relative;}.left{position: absolute;width: 300px;height: 200px;background-color: yellow;}.right{position: absolute;top: 0;right: 0;width: 200px;height: 200px;background-color: blue;}.middle{height: 200px;margin-left: 300px;margin-right: 200px;background-color: green;}</style>
</head>
<body><div class="container"><div class="left"></div><div class="right"></div><div class="middle"></div></div>
</body>
6.Grid网格布局
.container{
display: grid;
width: 100%;
/* 行高 */
grid-template-rows: 100px;
/* 列属性 */
grid-template-columns: 300px auto 200px;
}
<style>*{margin: 0;padding: 0;}.container{display: grid;width: 100%;/* 行高 */grid-template-rows: 100px;/* 列属性 */grid-template-columns: 300px auto 200px;}.left{background-color: yellow;}.middle{background-color: green;}.right{background-color: blue;}</style>
</head>
<body><div class="container"><div class="left"></div><div class="middle"></div><div class="right"></div></div>
</body>
9.js数据类型
基本数据:number string boolenl undefined null(es6) bigint symbol存储方式:值存储栈,占用空间小。频繁使用
引用:object (普通对象、数组、函数,日期) 堆 大
10.null undefined
Null 是定义并赋值空,值未设置; undefined是未定义
11.js判断变量
Typeof (常用于判断基本数据类型,引用:function,object) 根据底层数据存储的二进制前三位判断
Instanceof (主要用于区分引用数据类型,检测过程比较繁琐)验证当前类的原型prototype是否会出现在实例的原型链上,只要在原型链上结果true.
Object.prototype.toString.call() 通用 Object.prototype.toString.表示一个对象返回类型的字符串,call方法可以改变this的指向,把Object.prototype.toString()方法指向不同的数据类型,返回不同的结果。
Constructor ((引用数据类型)根据构造器判断
12.数组去重
数组去重的方法(十种方法)-CSDN博客
1、for循环+indexof,返回不为1的push到空数组中;
2、filter+indexof,返回为true的项组成的新数组 ;
3、es6新增数据结构set,set不允许出现重复的元素,array.from方法。
const newArr = Array.from(new Set(arr))
console.log(newArr)
13.伪数组和数组
伪数组 (1)类型object (2)可以用index获取某个元素,使用length属性查看长度,不能使用其他的数组方法 。(3)不能改变长度(4)遍历使用for in
数组 (1)类型array
伪数组转为真数组:
14.map foreach
Map 分配内存空间创建并存储和返回一个新的数组 不会改变原数组 ,快
Foreach 默认没有返回值(返回结果undefined)
15.Es6箭头函数
(1) 没有this this从外部获取 继承外部执行上下文的this
(2)不能作为构造函数,不能使用new关键字
(3)没有prototype原型属性
(4)没有arguments内置对象
16.事件扩展符(...)
应用场景
JS篇面试题16-Es6中的事件扩展符在什么场景下使用-CSDN博客
数组克隆(浅拷贝) let b = [...a]
数组合并 let c = [...a,...b]
类数组转换为真正的数组
数组去重...new Set(arr)
17.闭包
闭包:什么是闭包,闭包的用途及优缺点-CSDN博客
函数的内部函数能够访问到外部函数变量 内部函数=闭包
原理:作用域链 当前函数能访问到上级函数作用域的变量
作用;保存变量(让变量始终保存在内存当中,不会随着函数的结束自动销毁) 防止全局污染 节流防抖
影响:内存泄漏
闭包的特性:闭包函数被return到了外部,在函数执行结束后没有被销毁,所以在函数外部也能访问函数内部的局部变量;由于垃圾回收器不会将闭包中的变量销毁,于是就造成了内存泄漏,内存泄漏多了容易导致内存溢出; 4.闭包的应用:实现柯里化、防抖节流;
18.js变量提升 var let const
变量提升是指 js的变量和函数声明会在代码编译时提升到代码最前面
var声明的变量存在声明提升(变量提升时只有声明被提升,赋值不会)
函数声明提升比变量提升优先。
Let const声明的变量不会提升 声明的变量必须先声明才能使用 暂时性死区:在该作用域中 无法在变量声明之前去使用
19.this指向(普通函数 箭头函数)
普通函数this指向(1)一函数调用this,指向window (2)以方法形式调用,指向定义处,(谁调用指向谁)。
箭头函数this,继承函数所在执行上下文中的ths
20.Call apply bind
三者的作用都是改变this指向。
call apply 会直接执行函数。第一个参数都是this的新指向。
call和bind 的第二个参数是参数列表,但是apply是一个数组。
bind不会直接执行函数,只能改变一次函数的指向。
21.js继承的方法 优缺点
JavaScript继承的多种方式及优缺点_js继承方式及其优缺点-CSDN博客
(1)原型链继承
- 优点:实现简单,一行代码
- 缺点:数据共享了,c1和c2共享了同一个原型对象
(2)借用构造函数继承
- 优点:
- 避免了引用类型的属性被所有的实例共享;
- 可以在
Children
中向Person
传参
- 缺点:
- 方法都在构造函数中定义,每次创建实例都会创建一遍方法;
- 不能继承
Person
原型上的方法/属性
(3)组合继承
- 融合原型链继承和构造函数的优点,是
JavaScript
中最常用的继承模式
(4)寄生式继承
(5)class继承
- 通过
class
关键字声明类 - 子类通过
extends
关键字继承父类
22.new 会发生什么
分配内存空间,创建一个新对象
为新创建的对象添加属性,将新对象的原型proto指向父级构造函数的原型对象prototype
让函数的this指向新对象
判断有无返回对象,如果没有那么会自动返回这个新对象。
23.defer和async区别
将html解析变为异步
Defer js加载完之后不会立即执行 等到html也解析完之后才会执行
Async js加载完之后立即执行 而且阻塞html解析
24.promise? 使用方法
是一个构造函数,异步编程的一种解决方案 解决地狱回调 (异步多层嵌套回调)
有三种状态: resolved 成功 rejected 失败 pending执行中
new Promise((resolve,rejected)=>{}).then(res=>{}).catch(err=>{});
可以用then查看成功信息 catch捕捉错误信息,可以链式调用
24.js实现异步
详解JS的四种异步解决方案!_js 异步-CSDN博客
(1)回调函数(会出现回调地狱问题)
(2)Generator
「generator」是ES6提出的一种异步编程的方案。因为手动创建一个iterator十分麻烦,因此ES6推出了「generator」,用于更方便的创建iterator。
也就是说,「generator」就是一个返回值为iterator对象的函数。
function* createIterator() {yield 1;yield 2;yield 3;
}
// generators可以像正常函数一样被调用,不同的是会返回一个 iterator
let iterator = createIterator();
console.log(iterator.next().value); // 1
console.log(iterator.next().value); // 2
console.log(iterator.next().value); // 3
(3)promise
const promise = new Promise((resolve, reject) => {resolve('a');
});
promise.then((arg) => { console.log(`执行resolve,参数是${arg}`) }).catch((arg) => { console.log(`执行reject,参数是${arg}`) }).finally(() => { console.log('结束promise') });
如果我们需要嵌套执行异步代码,相比于回调函数来说,「Promise」的执行方式如下列代码所示:
var promise = new Promise((reslove, reject) => {setTimeout(() => {console.log('执行大量代码');}, 2000);//resolve('我成功了'); //resolve 之后变成了 成功状态 fulfilled// reject('我失败了'); //reject 之后promise状态变为 失败状态});//promise 的then() 在成功状态的时候被触发 resolve(res) res可以传递参数//promise 的catch() 在失败状态的时候被吃法 reject(err) err可以传递参数promise.then((res) => {console.log(res);}).catch((err) => {console.log(err);})
即通过then来实现多级嵌套(「链式调用」)
(4)Async/await
「async/await」是ES7提出的关于异步的终极解决方案。使得我们可以通过同步代码来达到异步的效果」。
async function callAll(){const count = await counter(1);const sum = await adder(count, 3);console.log(await delay(sum));
}
callAll();// 5
25.cookie sessionstorage localstorage
都是浏览器存储,都存储在浏览器本地,都遵循同源原则
Cookie 生命周期是由服务器端在写入时就设置好的 存储空间小存储登录验证信息
localstorage写入时就存在 需要手动清除 存储不一变动信息
sessionstorage页面关闭时自动清除 检测用户是否刷新进入页面
前端给后端发送请求时会自动携带cookie的数据
26.如何实现可过期的localstorage数据
惰性删除(用到再删)和定时删除()
惰性删除存储的数据类型是个对象,该对象有两个key,一个是要存储的value值,另一个是当前时间。获取数据的时候,拿到存储的时间和当前时间做对比,如果超过过期时间就清除Cookie。 定时删除:没敢喝一段时间删除一次。token存储在LocalStorage中,要清空
27.token能放在cookie中吗
1.实现上是可以的,功能上不推荐,容易产生csrf问题
2.`token`可以存放在`Cookie`中,`token` 是否过期,应该由后端来判断,不该前端来判断,所以`token`存储在`cookie`中只要不设置`cookie`的过期时间就ok了,如果 `token` 失效,就让后端在接口中返回固定的状态表示`token` 失效,需要重新登录,再重新登录的时候,重新设置 `cookie` 中的 `token` 就行
(1)token的认证流程
1. 客户端使用用户名跟密码请求登录
2. 服务端收到请求,去验证用户名与密码
3. 验证成功后,服务端签发一个 token ,并把它发送给客户端
4. 客户端接收 token 以后会把它存储起来,比如放在 cookie 里或者 localStorage 里
5. 客户端每次发送请求时都需要带着服务端签发的 token(把 token 放到 HTTP 的 Header 里)
6. 服务端收到请求后,需要验证请求里带有的 token ,如验证成功则返回对应的数据
28.axios拦截器原理 应用
基于promise的http库,分为请求 响应。
拦截器原理:创建一个chn数组,数组中保存了拦截器相应的方法及dispatchRequest(dispatchRequest这个函数调用才会真正的开始下发请求),把拦截器的方法放到chn数组中dispatchRequest的前面,把响应拦截器的方法放到chn数组中dispatchRequest的后面,把请求拦截器和响应拦截器forEach将他们分unshift,push到chn数组中,为了保证他们的执行顺序,需要使用promise,以出列的方式对chn数组中的方法挨个执行。
应用:
1.请求拦截器用于在接口请求之前做的处理,比如为每个请求带上相应的参数(token,时间戳等)。
3.返回拦截器用于在接口返回之后做的处理,比如对返回的状态进行判断(token是否过期)
29.创建ajax过程
创建AJAX五大基本步骤_创建ajax的过程-CSDN博客
1.创建`XMLHttpRequest`对象,创建一个异步调用对象
2.创建一个新的`HTTP`请求,并指定该`HTTP`请求的方法、`URL`及验证信息.
3.设置响应`HTTP`请求状态变化的函数.
4.发送`HTTP`请求
1.var_xhr=new_XMLHttpRequest()
2.xhr.open("GET","",true)
3.xhr.onreadystatechange=fuction(){}
4.xhr.send()
30.vue2和3区别
Vue2
选项式api
支持单个根节点组件
响应式实现原理:es5的object defineproperty
指令优先级:v-for 比v-if优先生效
生命周期:
Beforecreate created beforemount mounted beforeupdate updated
Vue3
组合式api
支持多个根节点组件
响应式实现原理:采用proxy对象
指令优先级:v-if 比v-for优先生效
生命周期
Setup onbeforemount onmounted onbeforeupdate onupdated
31.v if v show
控制元素的显示与隐藏
Vif 本质是动态的向dom树中添加或者删除dom元素 适用于少次操作
Vshow 本质是控制css的display none属性 适用于频繁操作某个节点使用
32.元素显示与隐藏
Display none 回流重绘 改变布局,布局和位置发生变化
Visibility hidden 回流 未改变布局
Opacity 0 回流 未改变布局
33.浅拷贝 深拷贝
浅拷贝 复制的是引用地址,对象的顶层属性。复制后对象修改会影响源对象。
深拷贝 复制对象的所有层级属性,是对象的值。复制后的对象修改不影响源对象。
34.bom dom
Dom 文档对象模型 把文档当成一个对象 这个对象定义了处理网页的方法和接口
Bom 浏览器对象模型 把 与浏览器进行交互的方法和接口