一. HTML
1. HTML 语义化
HTML 语义化就是使用正确的标签(总结)段落就写 p 标签,标题就写 h1 标签,文章就写article标签,视频就写video标签,等等。
<html>
<body>
<header></header>
<main>
<section>
<h1></h1>
<p></p>
</section>
</main>
<footer></footer>
</body>
</html>
2. meta viewpor
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1">
//初始化width等于设备宽度,不允许缩放
移动设备默认的viewport是layout viewport,,但在进行移动设备网站的开发时,需要的是ideal viewport。要得到ideal viewport,需要用到meta标签。
meta viewport的六个属性:
-
width : 设置layout viewport 的宽度,为一个正整数,或字符串"width-device"
-
height: 设置layout viewport的高度,不常用。
-
initial-scale:初始缩放值。
-
maximum:最大缩放值
-
minimum:最小缩放值
-
use-scalable:是否允许用户进行缩放,值为"no"或"yes"
3. HTML 5 标签
canvas的基本API
fillRect(x, y, width, height)
绘制一个填充的矩形
strokeRect(x, y, width, height)
绘制一个矩形的边框
clearRect(x, y, width, height)
清除指定矩形区域,让清除部分完全透明
function draw() {
var canvas = document.getElementById('canvas');
//获取到DOM元素
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
//获取到绘制上下文
ctx.fillRect(25, 25, 100, 100);
ctx.clearRect(45, 45, 60, 60);
ctx.strokeRect(50, 50, 50, 50);
}
}
绘制路径
beginPath()
新建一条路径,生成之后,图形绘制命令被指向到路径上生成路径
closePath()
闭合路径之后图形绘制命令又重新指向到上下文中
stroke()
通过线条来绘制图形轮廓
fill()
通过填充路径的内容区域生成实心的图形
当你调用fill()函数时,所有没有闭合的形状都会自动闭合,所以你不需要调用closePath()函数。但是调用stroke()时不会自动闭合。
function draw() {
var canvas = document.getElementById('canvas');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.moveTo(75, 50);
ctx.lineTo(100, 75);
ctx.lineTo(100, 25);
ctx.fill();
}
}
二. CSS
1. 盒模型
见个人博客
2. 垂直居中
(1)table自带垂直居中
(2)给inline-block元素添加前后伪元素
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<div class="parent">
<div class="child">
一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串
</div>
</div>
</body>
</html>
//css
.parent{
border: 3px solid red;
height: 600px;
text-align: center;
}
.child{
border: 3px solid black;
display: inline-block;
width: 300px;
vertical-align: middle;
}
.parent::before{
content:'';
outline: 3px solid red;
display: inline-block;
height: 100%;
vertical-align: middle;
}
.parent::after{
content:'';
outline: 3px solid red;
display: inline-block;
height: 100%;
vertical-align: middle;
}
(3)div转成table
<body>
<div class="table">
<div class="td">
<div class="child">
一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字
</div>
</div>
</div>
</body>
//css
div.table{
display: table;
border: 1px solid red;
height: 600px;
}
div.tr{
display: table-row;
border: 1px solid green;
}
div.td{
display: table-cell;
border: 1px solid blue;
vertical-align: middle;
}
.child{
border: 10px solid black;
}
(4)绝对定位
<div class="parent">
<div class="child">
一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字
</div>
</div>
//css
.parent{
height: 600px;
border: 1px solid red;
position: relative;
}
.child{
border: 1px solid green;
width: 300px;
height: 100px;
position: absolute;
top: 50%;
left: 50%;
margin-left: -150px;
margin-top: -50px;
// 可代替transform: translateX(-50%) translateY(-50%);
}
(5)absolute+margin auto
<div class="parent">
<div class="child">
一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字
</div>
</div>
//css
.parent{
height: 600px;
border: 1px solid red;
position: relative;
}
.child{
border: 1px solid green;
position: absolute;
width: 300px;
height: 200px;
margin: auto;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
(6)flex
<div class="parent">
<div class="child">
一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字
</div>
</div>
//css
.parent{
height: 600px;
border: 3px solid red;
display: flex;
justify-content: center;//水平对齐
align-items: center;//垂直对齐
}
.child{
border: 3px solid green;
width: 300px;
}
3. BFC(block format context)
(1)什么是BFC
块级格式化上下文
首先BFC是一个名词,是一个独立的布局环境,我们可以理解为一个箱子(实际上是看不见摸不着的),箱子里面物品的摆放是不受外界的影响的。转换为BFC的理解则是:BFC中的元素的布局是不受外界的影响我们往往利用这个特性来消除浮动元素对其非浮动的兄弟元素和其子元素带来的影响。
BFC布局规则:
- 内部的Box会在垂直方向,一个接一个地放置。
- Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠
- 每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
- BFC的区域不会与float box重叠。
- BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
- 计算BFC的高度时,浮动元素也参与计算
哪些些元素生成BFC
- 元素
- float属性不为none
- position为absolute或fixed
- display为inline-block, table-cell, table-caption, flex, inline-flex
- overflow不为visible
产生垂直外边距合并的必备条件
- 必须是处于常规文档流(非float和绝对定位)的块级盒子,并且处于同一个BFC当中
- 没有线盒,没有空隙(clearance,下面会讲到),没有padding和border将他们分隔开
4. 清除浮动
这里有一篇关于清除浮动的博客
.clearfix:after{
content: '';
display: block; /*或者 table*/
clear: both;
}
.clearfix{
zoom: 1; /* IE 兼容*/
}
原理差不多就是,给父元素加一个伪元素作为最后一个元素,这个元素不允许前后有浮动元素这样原来由于浮动而坍缩的父元素又可以重新将浮动元素包裹在内
5. CSS选择器
--basic selector
(1)元素选择器
p,span,div,a{}
(2)类选择器
.className{}
(3)ID选择器
#ID{}
(4)通配选择器
*{}
(5)属性选择器
a[href$=".org"]{}
比较多,基本用法就是选择一个拥有匹配属性的标签,可以配合正则表达式使用
--Combinators
(1)相邻兄弟选择器
/* 图片后面紧跟着的段落将被选中 */
img + p {
font-style: bold;
}
//位置相邻,拥有共同父元素,选中的是第二个元素p
(2)兄弟选择符
p ~ span {
color: red;
}
//位置无须紧邻,只须同层级,A~B 选择A元素之后所有同层级B元素。
(3)子代选择器
div > span {
background-color: DodgerBlue;
}
//直接子代,子代中的子代不算
(4)后代选择器
div span { background-color: DodgerBlue; }
<div>
<span>Span 1.
<span>Span 2.</span>
</span>
</div>
<span>Span 3.</span>
//选中span1, span2不限于直接后代
--伪类选择器
有很多,比如:hover,:active等用于修饰基本选择器这里介绍下常用的:nth-child)
tr:nth-child(n)
找到当前元素的所有兄弟元素并从上到下排序(0~x),你可以对表达式进行修改比如
tr:nth-child(2n)
//找到所有偶数项
span:nth-of-type(2n+1)
//只对span进行排序,忽略其余标签
选择器优先级
概括一下就是
- 选择器越具体优先级越高
- 后定义的覆盖前定义的
- 行内优先级高
- !important最高,慎用
6. 元素高度问题
(1) clientHeight
区域:content+padding
其中clientWidth不包括滚动条宽度
(2) offsetHeight
区域:content+padding+border
(3) scrollHeight
区域:子元素实际高度
子元素高度小于父元素高度时出现的滚动条,此时子元素可见和非可见区域之和也就是实际的高度
scrollHeight>=clientHeight恒成立。在有滚动条时讨论scrollHeight才有意义,
在没有滚动条时scrollHeight==clientHeight恒成立。单位px,只读元素。
(4) scrollTop
区域:可见区域上半部分不可见区
(5) offsetTop
区域:当前元素顶部距离最近父元素顶部的距离,和有没有滚动条没有关系
Element.getBoundingClientRect()
属性:left, top, right, bottom, x, y, width, 和 height
注:这里的参考点都是视图窗口的左上角,也就是说当存在滚动行为时,其值会相应改变,若要获取绝对定位值,需加上window.scrollX 和 window.scrollY
如果需要更好的跨浏览器兼容性,请使用 window.pageXOffset 和 window.pageYOffset 代替 window.scrollX 和 window.scrollY
三. 原生JS
1. 函数节流
所谓函数节流就是让一个函数间隔一段时间后才能再次执行,等于是给他一个冷却时间
function throttle(fn, delay){
let coolDowm = false
return function(){
if(!coolDown){
fn.apply(this, arguments)
coolDown = true
setTimeout(()=>coolDown = false, delay)
}
}
}
我们构造一个函数,声明一个coolDown变量,他和下面的函数形成闭包,我们将想要执行的函数fn和delay也就是冷却时间传入这个函数,初始化coolDown为false,也就是不在冷却可以执行函数,执行完成以后将coolDown变成true,进入冷却,定义一个延迟执行函数setTimeout,在delay时间后将coolDown变成false,可以再次调用fn
2. 函数防抖
function debounce(fn, delay){
let timerId = null
return function(){
const context = this
if(timerId){window.clearTimeout(timerId)}
timerId = setTimeout(()=>{
fn.apply(context, arguments)
timerId = null
},delay)
}
}
const debounced = debounce(()=>console.log('hi'))
debounced()
debounced()
//只打印了一次hi
函数防抖相当于一个限制器,如果你在短时间内连续调用一个函数,那么他会只会执行一次,比如用户连点一个按钮
3. AJAX
AJAX其实就是用JS发送一个HTTP请求,但是正常情况下是不允许跨域的,除非用cors
var request = new XMLHttpRequest()
request.open('GET', '/a/b/c?name=ff', true);
request.onreadystatechange = function () {
if(request.readyState === 4 && request.status === 200) {
console.log(request.responseText);
}};
request.send();
或者
var request = new XMLHttpRequest()
request.open('GET', '/a/b/c?name=ff', true)
request.onload = ()=> console.log(request.responseText)
request.send()
用promise来对其进行一个封装
function getJSON (url) {
return new Promise( (resolve, reject) => {
var xhr = new XMLHttpRequest()
xhr.open('GET', url, true)
xhr.onreadystatechange = function () {
if (this.readyState === 4) {
if (this.status === 200) {
resolve(this.responseText, this)
} else {
var resJson = { code: this.status, response: this.response }
reject(resJson, this)
}
}
}
xhr.send()
})
}
四 DOM
1. 事件委托
详见链接博客
2. 如何写一个可拖拽方块
let move=document.getElementById('move')
let draging=false
let position=null
move.addEventListener('mousedown',(e)=>{
draging=true
let x=e.clientX
let y=e.clientY
position=[x,y]
})
document.addEventListener('mousemove',(e)=>{
if(draging===false){return}
let x=e.clientX
let y=e.clientY
let deltax=e.clientX-position[0]
let deltay=e.clientY-position[1]
let left=parseInt(move.style.left||0)
let top=parseInt(move.style.top||0)
move.style.left=deltax+left+'px'
move.style.top=deltay+top+'px'
position=[x,y]
})
document.addEventListener('mouseup',e=>{
draging=false
})
五. HTTP
1. HTTP缓存
引此,讲的非常清晰易懂
浏览器第一次向一个web服务器发起http请求后,服务器会返回请求的资源,并且在响应头中添加一些有关缓存的字段如:Cache-Control、Expires、Last-Modified、ETag、Date等等。之后浏览器再向该服务器请求该资源就可以视情况使用强缓存和协商缓存。
强缓存
浏览器直接从本地缓存中获取数据,不与服务器进行交互。
协商缓存
浏览器发送请求到服务器,服务器判定是否可使用本地缓存
(1)强缓存
当用户第一次访问服务器时,服务器会在响应头中添加Cache-Control、Expires两个用来判断缓存时间的字段,
当浏览器第二次访时,会先检查Cache-Control中的s-maxage或max-age指令若有,则使用响应报文生成时间Date + s-maxage/max-age获得过期时间,再与当前时间进行对比(s-maxage适用于多用户使用的公共缓存服务器)
如果没有Cache-Control的s-maxage或max-age指令,则比较Expires中的过期时间与当前时间。Expires是一个绝对时间。
经过上述两步判断后,若缓存未过期,返回状态码为200,则直接从本地读取缓存
(2)协商缓存
在上一步中如果发现缓存时间已经过期了,就会向服务器发起请求,但是这并不意味着资源一定会不同,因为服务器端文件可能并没有发生改变,
所以这时候就要用ETag和Last-Modified来判断资源是否发生了改变,这两个数值是服务器为每份资源分配的唯一标识字符串,因此他们是唯一的
他们的原理是服务器第一次返回资源的时候回附带一个ETag字段,并且服务器端的ETag也会动态更新
当浏览器再次请求时会在报文中添加一个If-None-Match字段,它的值就是上一次服务器返回的ETag值
服务器此时就会比对两个ETag是否一致,如果一致则返回304,表示浏览器可以使用本地缓存并将这个ETag加入相应头中返回,尽管它未改变
Last-Modified和If-Modified-Since
他俩都是用来比对服务器端和浏览器端资源是否相同的一个字段,他俩的主要区别有以下
- 当返回码为304即浏览器可以使用本地缓存时,服务器这里不会像
ETag一样返回Last-Modified字段 - 浏览器在协商请求时
Last-Modifie是写在If-Modified-Since字段中的
ETag的优势
- 服务器端文件可能定期更新,这样他
Last-Modifie改变而ETag不变,节省了不必要的传输 - 某些文件的更改事件在1s以内,而
Last-Modifie不能获取到这个更新,而ETag则对应任何更改的文件 - 某些服务器不能得到精确的文件更改事件
所以服务器会优先校验ETag,而实际情况是两种校验一起使用
2.GET和POST
- GET在浏览器回退时是无害的,而POST会再次提交请求。
- GET产生的URL地址可以被Bookmark,而POST不可以。
- GET请求会被浏览器主动cache,而POST不会,除非手动设置。
- GET请求只能进行url编码,而POST支持多种编码方式。
- GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。
- GET请求在URL中传送的参数是有长度限制的,而POST么有。
- 对参数的数据类型,GET只接受ASCII字符,而POST没有限制。
- GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。
- GET参数通过URL传递,POST放在Request body中。
但是两者在TCP/IP层面实现是相同的所以他属于HTTP层的一个规范
但是两者在幂等性方面是不同的
所谓幂等性是数学中的一个概念,表达的是N次变换与1次变换的结果相同
加入我多次GET,就相当于我翻开一本书然后看,我重复看n此这本书也不会发生改变
但是POST就不是幂等的,因为我POST相当于在服务器端上传两份资源,他们的URI(Uniform Resource Identifier)是不一样的,所以如果POST n次,那么会创建n个文件
3. Cookie V.S. LocalStorage V.S. SessionStorage V.S. Session
首先Cookie是实际存在的一个东西,他是你第一次访问服务器时,比如用户登录后,服务器给你返回一个标识符,相当于一个身份证,当你再次访问服务器就要在请求头中带上Cookie,这样服务器就能识别你的身份,cookie是存在于客户端的,并且有一定的生存时间,过期会被销毁
而session是服务器与客户端保持会话的一种方式,他的实现一般是依靠sessinoid,而这个id需要通过cookie存储在客户端。当程序需要为某个客户端的请求创建一个session时,服务器首先检查这个客户端的请求里是否已包含一个session id。
如果有则表明已经为此客户端创建过session,服务器就按照这个session id查找出服务器端保存的session(查找失败的话,会创建一个新的session)。如果请求中不包含session id,则就回创建一个新的session,并把session id返回到客户端进行保存。
LocalStorage
这个主要是浏览器中用于存储一些不重要的文件使用,他的容量一般为5M左右,而cookie一般只有4k大小
SessionStorage
也是用于在客户端存储文件的一块区域,他和LocalStorage 的主要区别是,SessionStorage会在session结束时被销毁