HTML
HTML语义化
- 让人更容易读懂(增加代码可读性)
- 让搜索引擎更容易读懂( SEO )
块级,内联元素
- display: block/table;有div h1 h2 table ul ol p等
- display: inline/inline-block;有span img input button等
CSS
相邻元素的margin-top和margin-bottom会发生重叠
BFC
margin负值
左右固定,中间自适应
<style>
.contain {
padding-left: 150px;
padding-right: 100px;
}
.center {
float: left;
width: 100%;
background-color: aqua;
}
.left {
position: relative;
float: left;
width: 150px;
background-color: brown;
margin-left: -100%; //移动相当于父元素的宽度
right: 150px;
}
.right {
float: left;
width: 100px;
background-color: blueviolet;
margin-right: -100px; //相当于元素不占据位置,自然就排在第一行
}
</style>
<div class="contain">
<div class="center">center</div>//最重要的放在前面
<div class="left">left</div>
<div class="right">right</div>
</div>
水平,垂直居中
第三种要加上top:50%,left:50%,第三第四种不需要知道子元素宽高
line-height继承
body{
font-size:20px;
line-height:200%
}
p{
font-size:16px
}//p line-height:40px
JS
函数内所有自由变量的查找是在函数定义的地方,向上级作用域查找,不是在执行的地方
闭包的两种情况
点击都弹出10 只有点击后才执行函数,i早就变成10了
Map set
map与object的区别
- map任意类型可以是key
- 有序
- 操作快
set和数组的区别 - 无序
- 不能重复
DOM
渲染过程
- 根据html生成Domtree,css生成cssom,整合成render Tree
- 根据render tres渲染页面,遇到script暂停渲染,执行完再渲染
document load/ready
DOMContentLoaded DOM:dom渲染完,图片视频可能没有加载完,即可执行
window.onload:dom渲染完,图片视频加载完attribute property
插入多个子元素考虑性能
ajax
手写ajax
const xhr = new XMLHttpRequest()
xhr.open('GET', 'data/test', true)
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
alert(xhr.responseText)
} else {
console.log('其他情况')
}
}
}
xhr.send(null)
const xhr = new XMLHttpRequest()
xhr.open('POST', '、login', true)
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
alert(xhr.responseText)
} else {
console.log('其他情况')
}
}
}
const postData = {
username:'zhang',
password:'xxx'
}
xhr.send(JSON.stringify(postData))
promise
function ajax(url) {
const p = new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest()
xhr.open('GET', url, true)
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
resolve(JSON.parse(xhr.responseText))
} else if (xhr.status === 404) {
reject(new Error('404 not found'))
}
}
}
xhr.send(null)
})
return p
}
const url = '/login'
ajax(url)
.then((res) => console.log(res))
.catch((err) => console.error(err))
同源
防抖和节流
防抖和节流本质是不一样的。防抖是将多次执行变为最后一次执行,节流是将
多次执行变成每隔一段事件执行,封装函数使用闭包
防抖
例如输入框的input事件,一输入就会触发事件,要等n秒后执行
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<style></style>
<body>
<input type="text" id="input1" />
</body>
<script>
function debounce(fn, delay) {
let timer = null
return function () {
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
fn.apply(this, arguments)
timer = null
}, delay)
}
}
const input1 = document.getElementById('input1')
input1.addEventListener(
'keyup',
debounce(function () {
//这里不能写箭头函数
console.log(input1.value)
}, 1000)
)
</script>
</html>
节流
例如拖拽drapDOM元素,每次移动就会触发函数,要求每n秒监听一次
apply,call调用后会立即执行目标函数。bind不会执行
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<style>
#blue {
width: 200px;
height: 200px;
background-color: blue;
}
</style>
<body>
<div id="blue" draggable="true"></div>
</body>
<script>
function throttle(fn, delay) {
let timer = null
return function () {
if (timer) {
return
}//有定时器就退出
timer = setTimeout(() => {
//e传给的是throttle函数,而不是里面的fn函数,因此需要把arguments参数传到fn函数里,this代表那个绑定的DOM元素。否则e就是undefined.
fn.apply(this, arguments)
timer = null
}, delay)
}
}
const div1 = document.getElementById('blue')
div1.addEventListener(
'drag',
throttle(function (e) {
console.log(e.offsetX, e.offsetY)
},1000)
)
</script>
</html>
nodejs与前端js的区别
事件循环
- 微任务DON渲染前触发
- 宏任务DON渲染后触发
任务分为了同步任务和异步任务;而异步任务又可以分为微任务和宏任务。 执行一个宏任务(栈中没有就从事件队列中获取)
宏任务执行完毕后,立即执行当前微任务队列中的所有微任务(依次执行)
开始下一个宏任务(从事件队列中获取)
- 宏任务:
setTimeout
setInterval
js主代码
setImmediate(Node)
requestAnimationFrame(浏览器)
- 微任务:
process.nextTick
Promise的then方法
Promise和async中的立即执行
我们知道Promise中的异步体现在then和catch中,所以写在Promise中的代码是被当做同步任务立即执行的。而在async/await中,在await出现之前包括await,其中的代码也是立即执行的
async function async1() {
console.log('async1 start')
await async2()
setTimeout(() => {
console.log('setTimeout1')
}, 0)
}
async function async2() {
setTimeout(() => {
console.log('setTimeout2')
}, 0)
}
console.log('script start')
setTimeout(() => {
console.log('setTimeout3')
}, 0)
async1()
new Promise((resolve) => {
console.log('promise1')
resolve()
}).then(() => {
console.log('promise2')
})
console.log('script end')
```先执行所以同步任务,把setTimeout3放到宏任务队列,执行anync1,async1 start,执行async2,把setTimeout2放到宏任务队列,await后面的放到微任务队列,输出promise1,then后面的放到微任务队列,输出script end,按顺序执行微任务,发现第一个微任务里是个宏任务,把setTimeout1放到宏任务队列,输出promise2,按顺序执行宏任务。
script start
async1 start
promise1
script end
promise2
setTimeout3
setTimeout2
setTimeout1
http
状态码
200 301 302 304(协商)404 403(客户端) 500 504(服务端)
请求响应头
请求头
- Accept:浏览器可接受的数据格式
- Accept-Encoding:浏览器可接受的压缩算法
- Accept-Languange:浏览器可接受的语言
- Connection:keep-alive 一次Tcp连接重复使用
- User-Agent:浏览器信息
- content-type:返回数据格式
- content-length:返回数据大小
- content-Encoding:返回数据的压缩算法
响应头
- content-type:发送数据格式
缓存
先强后协商,强缓存过期在判断协商缓存强缓存
初次请求返回资源和Cache-Control,Cache-Control都值,max-age,过期时间,no-cache不用强缓存,no-store两种缓存都不用。expires已被该替代。协商缓存
服务端缓存策略,服务器判断客户端是否和服务端资源一样,一致返回304,否则返回200和最新资源,资源标识,第一次访问返回资源和资源标识。
在响应头中有两种:last-Modified资源的最后修改时间,Etag资源的唯一标识。 - 初次请求返回资源和last-modified,再次请求,请求头带上If-Modified-Since,返回304或资源和新的last-Modified。
- Etag差不多,根据文件内容生成,请求头带上If-None-Match,可以与last-Modified共存,优先级比last-Modified高
刷新
- 手动刷新:强制缓存失效,协商缓存有效
- 强制刷新:都失效
https证书
解决中间人攻击,里面有公钥和私钥,https有对称算法,非对称算法结合,首先使用公钥加密一个随机数,使用私钥解密随机数,使用这个随机数对传输数据进行对称加密,作为对称加密的公钥。xss xsrf
- xss 比如写一篇博客里面写上script,那么其他人点击进来会执行script,获取到用户cookie
,解决方法将<>转义 - xsrf 比如你登录的一个购物网站,此时打开一封包含image的邮件,因为图片不受同源策略影响,就可以拿到用户登录生成的cookie发送请求。解决方法是再次输入密码验证