【HTML5 笔记】基础内容
文章目录
- 01 canvas
- 1.1 canavs 的应用场景
- 1.2 canvas 发展历史
- 1.3 如何使用 canvas
- 1.4 两个对象
- 1.5 线段
- 1.6 矩形
- 1.7 擦除当前区域
- 1.8 弧形
- 1.9 圆角
- 1.10 贝塞尔曲线
- 1.11 坐标轴转换,对画布进行操作
- 1.12 填充图案
- 1.13 渐变
- 1.14 阴影
- 1.15 文本
- 1.16 线段样式
- 1.17 裁剪
- 1.18 合成
- 1.19 全局透明度
- 1.20 绘制图片
- 1.21 将 canvas 内容导出
- 1.22 获取 canvas 像素信息
- 1.23 RGBA 值
- 1.24 命中检测
- 1.25 非零绕数准则
- 1.26 如何解决 canvas 高分屏模糊问题
- 02 SVG(Scalable Vector Graphics)可缩放矢量图形
- 2.1 应用场景
- 2.2 SVG 元素
- 2.3 CSS 样式属性
- 2.4 path 元素
- 2.5 path 移动和直线命令
- 2.6 圆弧指令
- 2.7 贝塞尔曲线
- 2.8 自动生成路径
- 2.9 SVG 渐变
- 2.10 SVG 滤镜
- 2.11 SVG 路径动画
- 2.12 ViewBox
- 2.13 JS 生成 SVG 元素
- 03 requestAnimationFrame
- 04 客户端存储
- 4.1 storage
- 4.1.1 如何存储数据
- 4.1.2 如何取出数据
- 4.1.3 存储的有效期
- 4.1.4 作用域
- 4.1.5 API
- 4.2 cookie
- 4.2.1 设置 cookie 值
- 4.2.2 获得 cookie 值
- 4.2.3 设置 cookie 存储期限
- 4.2.4 domain
- 4.2.5 path
- 4.2.6 删除 cookie
- 05 history
- 5.1 通过修改 hash 和 hashchange 事件来实现历史纪录管理
- 5.1.1 参数
- 5.1.2 事件
- 06 Worker
- 6.1 worker 和主线程之间的通信
- 6.2 结束一个 worker
- 6.3 其他特性
- 07 多媒体 — audio 和 video
- 7.1 标签属性
- 7.2 脚本化
- 7.2.1 创建 audio/video 对象
- 7.2.2 设置属性
- 7.2.3 方法
- 7.2.4 事件
- 08 geolocation 对象
- 8.1 查看 geolocation 对象
- 8.2 getCurrentPosition()
- 8.3 watchPosition()
- 8.4 clearWatch()
- 09 devicemotion 对象
- 10 drag & drop
- 10.1 拖拽相关事件
- 10.2 DragEvent 事件对象
- 11 FileReader 构造函数
- 11.1 FileReader 方法
- 11.2 FileReader 事件
- 12 WebSocket
- 12.1 建立连接的握手
- 12.2 HTTP 三次握手
- 12.3 创建 WebSocket
- 12.4 WebSocket 方法
- 12.5 WebSocket 事件
- 12.6 WebSocket 的优点
01 canvas
1.1 canavs 的应用场景
- 游戏
- 图表
- 动画
- codepen.io(HTML5 动效)
1.2 canvas 发展历史
- 最早在 apple 的 safari 1.3 中引入
- ie9 之前的浏览器不支持 canvas
- http://caniuse.com/
1.3 如何使用 canvas
- 添加 canvas 标签
<canvas width=500 height=500></canvas>
- 获得 canavs 元素
var canvas =document.getElementById('myCanvas');
- 获得 canvas 上下文对象
var ctx = canvas.getContext('2d');
- WebGL 绘制 3d 图形时上下文时 ==>
var ctx = canvas.getContext('webgl');
- WebGL 绘制 3d 图形时上下文时 ==>
<!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>demo01</title>
</head>
<body><canvas id="canvas" width="500" height="500"></canvas><script>var canvas = document.getElementById('canvas');var ctx = canvas.getContext('2d');// var ctx = canvas.getContext('webgl');</script>
</body>
</html>
1.4 两个对象
- 元素对象(canvas 元素)和上下文对象(通过
getContext('2d')
方法获取到的CanvasRenderingContext2D 对象) - 元素对象相当于我们的画布,上下文对象相当于画笔,我们接下来的所有操作是基于上下文对象的
1.5 线段
ctx.moveTo(x, y)
起笔移动到 (x,y) 坐标点ctx.lineTo(x, y)
从当前点绘制直线到 (x,y) 点ctx.stroke()
描边,ctx.strokeStyle
设置边颜色ctx.fill()
填充,ctx.fillStyle
设置填充色ctx.lineWidth = 20
设置线段宽度ctx.closePath()
闭合当前路径 和回到起始点的区别- fill 和 stroke 方法都是作用在当前的所有子路径
- 完成一条路径后要重新开始另一条路径时必须使用 beginPath() 方法,betinPath 开始子路径的一个新的集合
<!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>demo01</title><style>#canvas{border: 2px solid #000;}</style>
</head>
<body><canvas id="canvas" width="500" height="500"></canvas><script>var canvas = document.getElementById('canvas');var ctx = canvas.getContext('2d');ctx.beginPath();ctx.lineWidth = 20;ctx.strokeStyle = 'red';ctx.fillStyle = 'green';ctx.moveTo(100, 100);ctx.lineTo(200, 100);ctx.lineTo(200, 200);ctx.lineTo(100, 200);ctx.lineTo(100, 100);ctx.stroke();ctx.fill();</script>
</body>
</html>
1.6 矩形
ctx.rect(x, y, dx, dy);
画矩形,从 (x,y) 坐标开始画,dx 为宽,dy 为高ctx.fillRect(x, y, dx, dy);
beginPath() + rect() + fill()ctx.strokeRect(x, y, w, h);
beginPath() + rect() + stroke()
<!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>demo01</title><style>#canvas{border: 2px solid #000;}</style>
</head>
<body><canvas id="canvas" width="500" height="500"></canvas><script>var canvas = document.getElementById('canvas');var ctx = canvas.getContext('2d');ctx.beginPath();ctx.rect(100, 100, 50, 100);ctx.stroke();ctx.beginPath();ctx.strokeRect(100, 250, 50, 100);ctx.beginPath();ctx.fillRect(250, 100, 50, 100);</script>
</body>
</html>
1.7 擦除当前区域
ctx.clearRect(x, y, dx, dy);
矩形擦除,从 (x,y) 开始擦,dx 为宽,dy 为高- 实现矩形落地动画
<!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>demo01</title><style>#canvas{border: 2px solid #000;}</style>
</head>
<body><canvas id="canvas" width="500" height="500"></canvas><script>var canvas = document.getElementById('canvas');var ctx = canvas.getContext('2d');var y = 50;function draw(y) {// ctx.beginPath();// ctx.rect(50, y, 20, 20);// ctx.fill();ctx.fillRect(50, y, 20, 20);}var timer = setInterval(function () {ctx.clearRect(0, 0, 500, 500);draw(y);y += 1;if( y > 480){clearInterval(timer);}}, 5);</script>
</body>
</html>
1.8 弧形
arc(x, y, r, 起始弧度, 结束弧度, 弧形的方向)
- (x,y) 圆心
- r 半径
- 0 顺时针,1 逆时针
<!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>demo01</title><style>#canvas{border: 2px solid #000;}</style>
</head>
<body><canvas id="canvas" width="500" height="500"></canvas><script>var canvas = document.getElementById('canvas');var ctx = canvas.getContext('2d');ctx.beginPath();ctx.moveTo(250, 250);ctx.lineTo(350, 250);ctx.arc(250, 250, 100, Math.PI * 0, Math.PI / 180 * -45, 1);ctx.lineTo(250, 250);ctx.stroke();</script>
</body>
</html>
1.9 圆角
ctx.arcTo(x1, y1, x2, y2, r)
绘制的弧线与当前点 (x,y) 和 (x1,y1) 连线,(x1,y1) 和 (x2、y2) 连线都相切
<!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>demo01</title><style>#canvas{border: 2px solid #000;}</style>
</head>
<body><canvas id="canvas" width="500" height="500"></canvas><script>var canvas = document.getElementById('canvas');var ctx = canvas.getContext('2d');ctx.beginPath();ctx.moveTo(50, 200);ctx.arcTo(300, 200, 250, 300, 50);ctx.stroke();</script>
</body>
</html>
<!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>demo01</title><style>#canvas{border: 2px solid #000;}</style>
</head>
<body><canvas id="canvas" width="500" height="500"></canvas><script>var canvas = document.getElementById('canvas');var ctx = canvas.getContext('2d');ctx.beginPath();ctx.moveTo(200, 100);ctx.arcTo(300, 100, 300, 300, 50);ctx.arcTo(300, 300, 100, 300, 50);ctx.arcTo(100, 300, 100, 100, 50);ctx.arcTo(100, 100, 300, 100, 50);ctx.closePath();ctx.stroke();</script>
</body>
</html>
1.10 贝塞尔曲线
https://blog.csdn.net/xiaozhangcsdn/article/details/98963937
quadraticCurveTo(x1, y1, ex, ey)
二次贝塞尔曲线- (x,y) 起始点 ==> P0
- (x1,y1) 控制点 ==> P1
(ex,ey) 结束点 ==> P2
bezierCurveTo(x1, y1, x2, y2, ex, ey)
三次贝塞尔曲线- (x,y) 起始点 ==> P0
- (x1,y1)、(x2,y2) 控制点 ==> P1、P2
- (ex,ey) 结束点 ==> P3
<!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>demo01</title><style>#canvas{border: 2px solid #000;}</style>
</head>
<body><canvas id="canvas" width="500" height="500"></canvas><script>var canvas = document.getElementById('canvas');var ctx = canvas.getContext('2d');ctx.beginPath();ctx.moveTo(100, 250);ctx.quadraticCurveTo(100, 0, 300, 300)ctx.stroke();</script>
</body>
</html>
<!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>demo01</title><style>#canvas{border: 2px solid #000;}</style>
</head>
<body><canvas id="canvas" width="500" height="500"></canvas><script>var canvas = document.getElementById('canvas');var ctx = canvas.getContext('2d');ctx.beginPath();ctx.moveTo(100, 400);ctx.bezierCurveTo(100, 100, 350, 100, 450, 450);ctx.stroke();</script>
</body>
</html>
1.11 坐标轴转换,对画布进行操作
translate(dx, dy)
重新映射画布上的(0,0)位置scale(sx, sy)
缩放当前绘图,变为原来坐标轴的 sx、sy 倍rotate(Math.PI)
旋转当前的绘图,以画布原点为旋转点save()
保存当前图像状态的一份拷贝restore()
从栈中弹出存储的图形状态并恢复setTransform(a, b, c, d, e, f)
复合属性,先重置再变换- 参数:a 水平旋转、b 水平倾斜、c 垂直倾斜、d 垂直缩放、e 水平移动、f 垂直移动
transform(a, b, c, d, e, f)
复合属性,在之前的基础上变换- 参数:a 水平旋转、b 水平倾斜、c 垂直倾斜、d 垂直缩放、e 水平移动、f 垂直移动
<!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>demo01</title><style>#canvas{border: 2px solid #000;}</style>
</head>
<body><canvas id="canvas" width="500" height="500"></canvas><script>var canvas = document.getElementById('canvas');var ctx = canvas.getContext('2d');ctx.save();ctx.beginPath();ctx.translate(100, 100);ctx.scale(2, 1);ctx.rotate(Math.PI / 180 * 20);ctx.fillRect(100, 100, 50, 50);ctx.stroke();ctx.beginPath();ctx.fillRect(100, 200, 100, 100);ctx.restore();ctx.beginPath();ctx.fillRect(100, 100, 100, 100);</script>
</body>
</html>
1.12 填充图案
createPattern(image,"repeat|repeat-x|repeat-y|no-repeat")
默认为 no-repeat- img元素(image 对象),canvas 元素,video 元素(有图形的)
<!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>demo01</title><style>#canvas{border: 2px solid #000;}</style>
</head>
<body><canvas id="canvas" width="500" height="500"></canvas><img src="./ocean.jpg"><script>var canvas = document.getElementById('canvas');var ctx = canvas.getContext('2d');var oImg = document.getElementsByTagName('img')[0];window.onload = function () {ctx.beginPath();ctx.fillStyle = ctx.createPattern(oImg, 'repeat');ctx.fillRect(0, 0, 500, 500)}</script>
</body>
</html>
1.13 渐变
createLinearGradient(x1, y1, x2, y2);
线性渐变,必须在填充渐变的区域里定义渐变,否则没有效果,从(x1,y1)渐变到(x2,y2)createRadialGradient(x1, y1, r1, x2, y2, r2);
径向渐变,内圆环圆心为(x1,y1),半径为 r1,外圆环圆心为(x2,y2),半径为 r2addColorStop(p, color);
,p 表示颜色范围
<!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>demo01</title><style>#canvas{border: 2px solid #000;}</style>
</head>
<body><canvas id="canvas" width="500" height="500"></canvas><!-- <img src="./ocean.jpg"> --><script>var canvas = document.getElementById('canvas');var ctx = canvas.getContext('2d');ctx.beginPath();var bg = ctx.createLinearGradient(0, 0, 0, 250);bg.addColorStop(0, '#000');bg.addColorStop(0.5, '#f00');bg.addColorStop(1, '#0f0');ctx.fillStyle = bg;ctx.fillRect(0, 0, 250, 250);ctx.beginPath();var bg = ctx.createLinearGradient(0, 250, 250, 250);bg.addColorStop(0, '#000');bg.addColorStop(0.5, '#f00');bg.addColorStop(1, '#0f0');ctx.fillStyle = bg;ctx.fillRect(0, 250, 250, 250);ctx.beginPath();var bg = ctx.createRadialGradient(375, 125, 50, 375, 125, 125);bg.addColorStop(0, '#f0f');bg.addColorStop(0.3, '#f00');bg.addColorStop(0.5, '#000');bg.addColorStop(0.8, '#00f');bg.addColorStop(1, '#ff0');ctx.fillStyle = bg;ctx.fillRect(250, 0, 250, 250);ctx.beginPath();var bg = ctx.createRadialGradient(375, 425, 50, 375, 375, 125);bg.addColorStop(0, '#f0f');bg.addColorStop(0.3, '#f00');bg.addColorStop(0.5, '#000');bg.addColorStop(0.8, '#00f');bg.addColorStop(1, '#ff0');ctx.fillStyle = bg;ctx.fillRect(250, 250, 250, 250);</script>
</body>
</html>
1.14 阴影
ctx.shadowColor
阴影颜色ctx.shadowOffsetX
水平偏移量ctx.shadowOffsetY
竖直偏移量ctx.shadowBlur
模糊半径
PS:这里的偏移量不受坐标系变换的影响
<!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>demo01</title><style>#canvas{border: 2px solid #000;}</style>
</head>
<body><canvas id="canvas" width="500" height="500"></canvas><!-- <img src="./ocean.jpg"> --><script>var canvas = document.getElementById('canvas');var ctx = canvas.getContext('2d');ctx.beginPath();ctx.arc(250, 250, 50, 0, Math.PI * 2);ctx.shadowColor = 'red';ctx.shadowOffsetX = 50;ctx.shadowOffsetY = 50;ctx.shadowBlur = 10;ctx.fill();</script>
</body>
</html>
1.15 文本
font
文本内容的字体属性textAlign = 'center|end|left|right|start';
文本内容的对齐方式textBaseline = 'alphabetic|top|hanging|middle|ideographic|bottom';
在绘制文本时使用的文本基线fillText()
绘制“被填充的”文本strokeText()
文本描边(无填充)measureText('hello world')
了解,返回包含指定文本宽度的对象console.log(ctx.measureText('hello world').width);
<!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>demo01</title><style>#canvas{border: 2px solid #000;}</style>
</head>
<body><canvas id="canvas" width="500" height="500"></canvas><!-- <img src="./ocean.jpg"> --><script>var canvas = document.getElementById('canvas');var ctx = canvas.getContext('2d');ctx.beginPath();ctx.fillStyle = 'green';ctx.font = '50px sans-serif';ctx.fillText('hello', 100, 100);ctx.beginPath();ctx.strokeStyle = 'green';ctx.font = '50px sans-serif';ctx.strokeText('hello', 300, 100);</script>
</body>
</html>
1.16 线段样式
lineCap = 'butt|round|square';
线条的结束端点样式,默认为 buttlineJoin = 'bevel|round|miter';
两条线相交时,所创建的拐角类型,默认为 miterlineWidth
线条宽度miterLimit
最大斜接长度
当 lineJoin 是 miter 时,用于控制斜接部分的长度
如果斜接长度超过 miterLimit 的值,变成 bevel
PS:实际运算是大于 miterLimit * lineWidth / 2 的值,了解就好
<!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>demo01</title><style>#canvas{border: 2px solid #000;}</style>
</head>
<body><canvas id="canvas" width="500" height="500"></canvas><!-- <img src="./ocean.jpg"> --><script>var canvas = document.getElementById('canvas');var ctx = canvas.getContext('2d');ctx.beginPath();ctx.moveTo(100, 100);ctx.lineTo(200, 100);ctx.lineWidth = 30;ctx.stroke();ctx.beginPath();ctx.moveTo(100, 150);ctx.lineTo(200, 150);ctx.lineWidth = 30;ctx.lineCap = 'butt';ctx.stroke();ctx.beginPath();ctx.moveTo(100, 200);ctx.lineTo(200, 200);ctx.lineWidth = 30;ctx.lineCap = 'round';ctx.stroke();ctx.beginPath();ctx.moveTo(100, 250);ctx.lineTo(200, 250);ctx.lineWidth = 30;ctx.lineCap = 'square';ctx.stroke();ctx.beginPath();ctx.moveTo(300, 50);ctx.lineTo(400, 50);ctx.lineTo(300, 100);ctx.lineWidth = 30;ctx.stroke();ctx.beginPath();ctx.moveTo(300, 50);ctx.lineTo(400, 50);ctx.lineTo(300, 100);ctx.lineWidth = 30;ctx.stroke();ctx.beginPath();ctx.moveTo(300, 150);ctx.lineTo(400, 150);ctx.lineTo(300, 200);ctx.lineWidth = 30;ctx.lineJoin = 'miter';ctx.stroke();ctx.beginPath();ctx.moveTo(300, 250);ctx.lineTo(400, 250);ctx.lineTo(300, 300);ctx.lineWidth = 30;ctx.lineJoin = 'round';ctx.stroke();ctx.beginPath();ctx.moveTo(300, 350);ctx.lineTo(400, 350);ctx.lineTo(300, 400);ctx.lineWidth = 30;ctx.lineJoin = 'bevel';ctx.stroke();</script>
</body>
</html>
1.17 裁剪
ctx.clip()
当前路径外的区域不再绘制
PS:可在 clip() 前用 save() 方法保存,后续通过 restore() 方法恢复
<!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>demo01</title><style>#canvas{border: 2px solid #000;}</style>
</head>
<body><canvas id="canvas" width="500" height="500"></canvas><!-- <img src="./ocean.jpg"> --><script>var canvas = document.getElementById('canvas');var ctx = canvas.getContext('2d');ctx.save();ctx.beginPath();ctx.arc(250, 250, 50, 0, Math.PI * 2);ctx.stroke();ctx.clip();ctx.beginPath();ctx.arc(300, 300, 50, 0, Math.PI * 2);ctx.fill();ctx.restore();ctx.beginPath();ctx.fillRect(400, 400, 50, 50);</script>
</body>
</html>
1.18 合成
ctx.globalCompositeOperation = 'source-over';
新像素和原像素的合并⽅方式- 11种值,默认 source-over,w3c标准
- source-over、source-atop、source-in、source-out、destination-over、destination-atop、destination-in、destination-out、copy、lighter、xor
- 常用 source-over、destination-over、copy
<!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>demo01</title><style>#canvas{border: 2px solid #000;}</style>
</head>
<body><canvas id="canvas" width="500" height="500"></canvas><!-- <img src="./ocean.jpg"> --><script>var canvas = document.getElementById('canvas');var ctx = canvas.getContext('2d');ctx.beginPath();ctx.fillStyle = 'red';ctx.fillRect(100, 100, 100, 100);ctx.globalCompositeOperation = 'xor';ctx.beginPath();ctx.fillStyle = 'green';ctx.arc(200, 200, 50, 0, Math.PI * 2);ctx.fill();</script>
</body>
</html>
1.19 全局透明度
globalAlpha
全局透明度ctx.globalAlpha = '0.5';
1.20 绘制图片
drawImage();
- 第一个参数是
img(Image,canvas,video)
,注:onload
- 第一个参数是
- 3个参数(x,y)
- 图片的(x,y)为起始点截取
- 5个参数(x,y,dx,dx)
- 以图片的(x,y)为起始点开始截取宽 dx 高 dy
- 9个参数(x1,y1,dx1,dy1,x2,y2,w2,h2)
- 前四个参数表示,以图片的(x1,y1)为起始点开始截取宽 dx1 高 dy1
- 后四个参数表示,在 canvas 上以(x1,y1)为起始点绘制宽 w2 高 h2
- 截到的图片会进行缩放以适应画布
<!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>demo01</title><style>#canvas{border: 2px solid #000;}</style>
</head>
<body><canvas id="canvas" width="500" height="500"></canvas><!-- <img src="./ocean.jpg"> --><img src="./ocean.jpg" id="draw"><script>var canvas = document.getElementById('canvas');var ctx = canvas.getContext('2d');var img = document.getElementsByTagName('img')[0];ctx.beginPath();window.onload = function () {ctx.drawImage(img, 100, 100, 100, 300, 50, 50, 300, 300);}</script>
</body>
</html>
1.21 将 canvas 内容导出
canvas.toDataURL();
是 canvas 自身的方法不是上下文对象- 将 canvas 的内容抽取成⼀张图片,base64 编码格式
- 注:引用外部图片时同源策略的限制,需要开虚拟主机
- 将 canvas 的内容放入 img 元素里
<!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>demo01</title><style>#canvas{border: 2px solid #000;}</style>
</head>
<body><canvas id="canvas" width="500" height="500"></canvas><img src="./ocean.jpg"><script>var canvas = document.getElementById('canvas');var ctx = canvas.getContext('2d');var img = document.getElementsByTagName('img')[0];ctx.beginPath();ctx.drawImage(img, 0, 0);var data = canvas.toDataURL();var img = document.createElement('img');img.src = data;document.body.appendChild(img);</script>
</body>
</html>
1.22 获取 canvas 像素信息
getImageData(x, y, dx, dy)
同源策略,开虚拟主机,获取 canvas 像素信息值console.log(ctx.getImageData(0, 0, 500, 500));
createImageData(w, h)
创建新的空白 ImageData 对象putImageData(imgData, x, y)
将图像数据放回画布上
<!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>demo01</title><style>#canvas{border: 2px solid #000;}</style>
</head>
<body><canvas id="canvas" width="500" height="500"></canvas><!-- <img src="./ocean.jpg"> --><script>var canvas = document.getElementById('canvas');var ctx = canvas.getContext('2d');ctx.beginPath();ctx.fillRect(300, 300, 100, 100);console.log(ctx.getImageData(0, 0, 500, 500));ctx.beginPath();var imgData = ctx.createImageData(100, 100);for (var i = 0; i < imgData.data.length; i += 4){imgData.data[i + 0] = 255;imgData.data[i + 1] = 0;imgData.data[i + 2] = 0;imgData.data[i + 3] = 255;}ctx.putImageData(imgData, 10, 10);</script>
</body>
</html>
1.23 RGBA 值
每个像素由 RGBA 四个值组成
R ==> 红色(0 - 255)
G ==> 绿色(0 - 255)
B ==> 蓝色(0 - 255)
A ==> alpha 通道(0 - 255;0 是透明的,255 是完全可见的)
1.24 命中检测
isPointInPath(x, y)
检测是否在区域内,chrome 与 safari 的区别isPointInStroke(x, y)
检测是否在线上- 还可以通过检测当前点的像素值,如果为透明,则该点不再路径上
<!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>demo01</title><style>#canvas{border: 2px solid #000;}</style>
</head>
<body><canvas id="canvas" width="500" height="500"></canvas><!-- <img src="./ocean.jpg"> --><script>var canvas = document.getElementById('canvas');var ctx = canvas.getContext('2d');ctx.beginPath();ctx.rect(100, 100 ,100, 100);ctx.stroke();console.log(ctx.isPointInPath(150, 150));console.log(ctx.isPointInStroke(150, 100));ctx.beginPath();ctx.strokeRect(300, 100 ,100, 100);console.log(ctx.isPointInPath(350, 150));console.log(ctx.isPointInStroke(350, 100));</script>
</body>
</html>
1.25 非零绕数准则
判断点 p 是否在多边形内,从点 p 向外做一条射线(可以任意方向),多边形的边从左到右经过射线时环绕数减 1,多边形的边从右往左经过射线时环绕数加 1,最后环数不为 0,即表示在多边形内部
1.26 如何解决 canvas 高分屏模糊问题
在分辨率比较高的屏幕,例如 ip6/6s/mac 等机器上,因为 canvs 绘制的是位图,所以会导致模糊,解决方法是根据屏幕分辨率修改 canvas 样式代码中的宽和高与 canvas 的 width 和 height 属性的比例
在 CSS 样式表中将 canvas 的宽高设置小,canvas标签将画布设置大
<!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>demo01</title><style>#canvas{border: 2px solid #000;height: 100px;width: 100px;}</style>
</head>
<body><canvas id="canvas" width="500" height="500"></canvas><!-- <img src="./ocean.jpg"> --><script>var canvas = document.getElementById('canvas');var ctx = canvas.getContext('2d');ctx.beginPath();ctx.rect(50, 50, 400, 400);ctx.stroke();</script>
</body>
</html>
02 SVG(Scalable Vector Graphics)可缩放矢量图形
https://www.w3school.com.cn/svg/index.asp
2.1 应用场景
- 图表
- 图标 icon
- 动效
- 矢量图
2.2 SVG 元素
- 开始
<svg width="500" height="500"></svg>
- 线段
<line x1="50" y1="20" x2="100" y2="20"></line>
- (x1,y1)起点,(x2,y2)终点
- CSS样式表:stroke 线条颜色,stroke-width 线条宽度
- 矩形
<rect x="50" y="50" width="100" height="100" rx="10" ry="20"></rect>
- (x,y)起点,rx 水平圆角半径,ry 垂直圆角半径
- CSS样式表:stroke 边框颜色,stroke-width 边框宽度,stroke-opacity 边框颜色的透明度,fill 填充颜色,fill-opacity 填充颜色透明度
- 圆形
<circle r="50" cx="250" cy="100"></circle>
- (cx,cy)圆心位置,r 圆半径
- 如果省略 cx 和 cy,圆的中心会被设置为(0,0)
- 椭圆
<ellipse rx="100" ry="50" cx="100" cy="200"></ellipse>
- (cx,cy)圆心位置,rx 水平半径,ry 垂直半径
- 折线
<polyline points="60 50, 75 35, 100 50, 125 35, 150 50, 175 35, 190 50"></polyline>
- 多边形
<polygon points="125 125,130 140,120 140"></polygon>
- ⽂本
<text x="125" y="220">hello,world</text>
<!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>demo02</title><style>svg{border: 2px solid #000;}line{stroke: #0f0;stroke-width: 10px;stroke-linecap: round;}polyline{fill: transparent;stroke: #000;stroke-width: 10px;stroke-linecap: round;stroke-linejoin: round;}polygon{fill: transparent;stroke: #000;stroke-width: 1px;}</style>
</head>
<body><svg width="500" height="500"><line x1="50" y1="20" x2="450" y2="20"></line><rect x="10" y="200" width="100" height="100" rx="10" ry="20"></rect><circle r="50" cx="200" cy="250"></circle><ellipse rx="100" ry="50" cx="390" cy="250"></ellipse><polyline points="60 100, 75 35, 100 100, 125 35, 150 100, 175 35, 190 100"></polyline><polygon points="125 125,130 200,200 140"></polygon><text x="350" y="50">hello,world</text></svg>
</body>
</html>
2.3 CSS 样式属性
fill
填充颜色fill-opacity
填充颜色透明度stroke
边框颜色stroke-width
边框宽度stroke-opacity
边框颜色透明度stroke-linecap
线条的结束端点样式stroke-linejoin
两条线相交时,所创建的拐角类型,默认为 miter
2.4 path 元素
https://segmentfault.com/a/1190000014620252
M/m (x, y)+
→ moveto,起始位置L /l (x, y)+
→ lineto,从当前位置绘制线段到指定位置H/h (x)+
→ horizontal lineto,从当前位置绘制一条水平线到达指定的 x 坐标V/v (y)+
→ vertical lineto,从当前位置绘制一条垂线达指定的 y 坐标C/c (x1, y1, x2, y2, x, y)+
→ curveto,从当前位置绘制三次贝塞尔曲线S/s (x2, y2, x, y)+
→ smooth curveto,从当前位置绘制光滑三次贝塞尔曲线,自动对称一个控制点,结束点(x,y)Q/q (x1, y1, x, y)+
→ quadratic Belzier curve,从当前位置绘制二次贝塞尔曲线T/t (x, y)+
→ smooth quadratic Belzier curveto,从当前位置绘制光滑二次贝塞尔曲线,自动对称一个控制点,结束点(x,y),就是一条直线A/a (rx, ry, xar, laf, sf, x, y)
→ elliptical Arc,从当前位置绘制弧线到指定位置Z/z
→ closepath,闭合当前路径- 大写表示绝对定位,小写表示相对定位
2.5 path 移动和直线命令
- M / m 指令和 L / l 指令
- M 指令和 L 指令
<path d = "M 10 10 L 20 10" />
- m 指令和 l 指令
<path d = "m 10 10 l 20 10" />
- 绝对坐标和相对坐标
- M 指令和 L 指令
- H 和 V 命令
<path d="M 100 100 H 200 V 200"/>
- Z 命令
<path d="M 100 100 H 200 V 200 z"/>
,注:Z 不区分大小写
<!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>demo02</title><style>svg{border: 2px solid #000;}path{fill: transparent;stroke: #000;stroke-width: 1px;}</style>
</head>
<body><svg width="500" height="500"><path d = "M 50 50 L 100 50" /><path d = "m 150 50 l 200 50" /><path d="M 100 100 H 200 V 200 z"/></svg>
</body>
</html>
2.6 圆弧指令
- A命令,七个参数,rx ry x-axis-rotation large-arc-flag sweep-flag x y
- rx ry:圆弧的 x 轴半径和 y 轴半径
- x-axis-rotation:圆弧相对 x 轴的旋转角度,默认是顺时针,可以设置负值
- large-arc-flag:表示圆弧路路径是大圆弧还是小圆弧,1大圆弧,0 小圆弧
- sweep-flag:表示从起点到终点是顺时针还是逆时针,1 表示顺时针,0 表示逆时针
- x y:表示终点坐标,绝对或相对
<path d="M 100 100 A 50 100 70 1 1 150 200"></path>
<!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>demo02</title><style>svg{border: 2px solid #000;}path{fill: transparent;stroke: #000;stroke-width: 1px;}</style>
</head>
<body><svg width="500" height="500"><path d="M 100 100 A 50 100 70 1 1 150 200"></path></svg>
</body>
</html>
2.7 贝塞尔曲线
https://blog.csdn.net/qq_41614928/article/details/90746382
https://blog.csdn.net/m0_50489096/article/details/115699025
- 二次贝塞尔曲线
- Q:控制点(x1,y1)、终点(x,y)
- T:终点(x,y),会自动补充一个控制点
- Q + T:它的第一个控制点,就会被假设成前一个控制点的对称点,相当于两段二次贝塞尔曲线
- 单独一个 T:控制点就会被认为和终点是同一个点,所以画出来的将是一条直线
- 三次贝塞尔曲线
- C:控制点(x1,y1)(x2,y2)、终点(x,y)
- S:控制点(x2,y2)、终点(x,y),会自动补充一个控制点
- C + S:它的第一个控制点,就会被假设成前一个控制点的对称点,相当于两段三次贝塞尔曲线
- 单独一个 S:它的两个控制点就会被假设为同一个点
<!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>demo02</title><style>svg{border: 2px solid #000;}path{fill: transparent;stroke: #000;stroke-width: 1px;}</style>
</head>
<body><svg width="500" height="500"><path d="M 100 150 Q 200 50 300 300 T 500 100"></path></svg>
</body>
</html>
2.8 自动生成路径
Method Draw
地址:https://editor.method.ac/
2.9 SVG 渐变
- 线性渐变
- (x1,y1)→(x2,y2)渐变方向
<!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>demo02</title><style>svg{border: 2px solid #000;}</style>
</head>
<body><svg width="500" height="500"><defs><linearGradient id="bg1" x1="0" y1="0" x2="0" y2="100%"><stop offset="0%" style="stop-color:rgb(255,255,0);"/><stop offset="100%" style="stop-color:rgb(255,0,0);"/></linearGradient></defs><rect x="0" y="0" width="500" height="500" style="fill:url(#bg1)"/></svg>
</body>
</html>
- 径向渐变
- (cx,cy)中心点坐标
- fx,fy 半径
<!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>demo02</title><style>svg{border: 2px solid #000;}</style>
</head>
<body><svg width="500" height="500"><defs><radialGradient id="bg2" cx="50%" cy="50%" r="50%" fx="50%" fy="50%"><stop offset="0%" style="stop-color:green;"/><stop offset="100%" style="stop-color:red;"/></radialGradient></defs><rect x="0" y="0" width="500" height="500" style="fill:url(#bg2)"/></svg>
</body>
</html>
2.10 SVG 滤镜
- 高斯滤镜
<!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>demo02</title><style>svg{border: 2px solid #000;}</style>
</head>
<body><svg width="500" height="500"><defs><filter id="Gaussian_Blur"><feGaussianBlur in="SourceGraphic" stdDeviation="50"/></filter></defs><rect x="0" y="0" width="500" height="500" fill=”yellow” style="filter:url(#Gaussian_Blur)"/></svg>
</body>
</html>
- 其他滤镜
- http://www.w3school.com.cn/svg/svg_filters_intro.asp
2.11 SVG 路径动画
stroke-dasharray
- 单个值,实线虚线为同一个
- 可设置多个值,依次为实线、虚线、实线、虚线…
stroke-dashoffset
动画实现原理,通过修改 stroke-dashoffset
的值让路路径慢慢地展现出来
<!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>demo02</title><style>svg{border: 2px solid #000;}path{fill: transparent;stroke: #000;stroke-width: 1px;stroke-dasharray: 300px;animation: dash 2s linear alternate infinite;}@keyframes dash {from{stroke-dashoffset: 0px;}to{stroke-dashoffset: 300px;}}</style>
</head>
<body><svg width="500" height="500"><path d="M 100 100 L 400 100"></path></svg>
</body>
</html>
getTotalLength()
路径总长度getPointAtLength(x)
路径上与起始点距离为 x 的点的坐标
注:严格来说上面两方法只适用于 path 元素,但各个浏览器实现起来都会有一点区别。例如谷歌浏览器也能获取到 line 元素的路径长度
<!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>demo02</title><style>svg{border: 2px solid #000;}path{fill: transparent;stroke: #000;stroke-width: 1px;}</style>
</head>
<body><svg width="500" height="500"><path d="M 100 100 L 400 100 400 400"></path></svg><script>var path = document.getElementsByTagName('path')[0];console.log(path.getTotalLength());console.log(path.getPointAtLength(200));</script>
</body>
</html>
2.12 ViewBox
https://zhuanlan.zhihu.com/p/422609203
https://blog.csdn.net/zhy13087344578/article/details/80336044
<svg width="500" height="500" viewBox="0,0,50,50"></svg>
- viewBox 用来设置 svg 的大小,以上代码相当于放大了 10 倍
- preserveAspectRatio
- xMin xMid xMax ==> x轴 左中右对齐
- yMin yMid yMax ==> y轴 左中右对齐
- meet slice none ==> 设置填充方式
<!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>demo02</title><style>svg{border: 2px solid #000;}path{fill: transparent;stroke: #000;stroke-width: 1px;}</style>
</head>
<body><svg width="500" height="500" viewBox="0 0 50 50"><path d="M 10 10 L 40 10 40 40"></path></svg>
</body>
</html>
2.13 JS 生成 SVG 元素
- 创建 SVG 元素需要指定命名空间
- SVG 元素对象一般通过调用 setAttribute() 方法来设定属性
<!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>demo02</title><style>svg{border: 2px solid #000;}</style>
</head>
<body><script>var str = 'http://www.w3.org/2000/svg',svg = document.createElementNS(str, 'svg');svg.setAttribute('width', 500);svg.setAttribute('height', 500);var rect = document.createElementNS(str, 'rect');rect.setAttribute('x', 100);rect.setAttribute('y', 100);rect.setAttribute('width', 100);rect.setAttribute('height', 100);rect.setAttribute('fill', '#0fc');svg.appendChild(rect);document.body.appendChild(svg);</script>
</body>
</html>
03 requestAnimationFrame
requestAnimationFrame 是浏览器用于定时循环操作的一个接口,类似 setTimeout,主要用途是按帧对网页进行重绘。
设置这个 API 的目的是为了让各种网页动画效果(DOM 动画、Canvas 动画、SVG 动画、WebGL 动画)能够有一个统一的刷新机制,从而节省系统资源,提高系统性能,改善视觉效果。代码中使用这个 API,就是告诉浏览器希望执行一个动画,让浏览器在下一个动画帧安排一次网页重绘。
requestAnimationFrame 的优势,在于充分利用显示器的刷新机制,比较节省系统资源。显示器有固定的刷新频率(60Hz 或 75Hz),也就是说,每秒最多只能重绘 60 次或 75 次,requestAnimationFrame 的基本思想就是与这个刷新频率保持同步,利用这个刷新频率进行页面重绘。此外,使用这个 API,一旦页面不处于浏览器的当前标签,就会自动停止刷新。这就节省了 CPU、GPU 和电力。
不过有一点需要注意,requestAnimationFrame 是在主线程上完成。这意味着,如果主线程非常繁忙,requestAnimationFrame 的动画效果会大打折扣。
requestAnimationFrame 使用一个回调函数作为参数。这个回调函数会在浏览器重绘之前调用。
1、页面刷新前执行一次
2、浏览器大概 1000ms 刷新 60 次 ==> 换算下来大概 16ms 刷新一次
3、cancelAnimationFrame
requestAnimationFrame(f)
cancelAnimationFrame(id)
4、用法和 setTimeout 类似
5、兼容性
// 兼容性写法
window.requestAnimFrame = (function(){return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (callback) {window.setTimeout(callback, 1000 / 60);};
})();
window.cancelAnimFrame = (function(){return window.cancelAnimationFrame || window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || window.oCancelAnimationFrame || window.msCancelAnimationFrame || function (id) {window.clearTimeout(id);};
})();
<!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>demo03</title><style>div{position: absolute;left: 0;width: 50px;height: 50px;background: #f00;}</style>
</head>
<body><div></div><script>var oDiv = document.getElementsByTagName('div')[0];// requestAnimFrame 绘制动画function fun() {var le = oDiv.offsetLeft;oDiv.style.left = le + 1 +'px';if(le < 500){var req = requestAnimationFrame(fun);}else{oDiv.style.left = 500 +'px';cancelAnimationFrame(req)}}fun();// setInterval 绘制动画// var timer = setInterval(function () {// var le = oDiv.offsetLeft;// oDiv.style.left = le + 1 +'px';// if(le > 500){// clearInterval(timer);// }// }, 16);</script>
</body>
</html>
04 客户端存储
4.1 storage
需要开启服务器,同源策略限制
localstorage
seesionstorage
4.1.1 如何存储数据
localStrorage.name = 'aimee';
存一个数据localStorage.info = JSON.stringify({name:'aimee,company: 'duyi'});
存一组数据,转换为字符串形式seesionstorage.name = 'aimee';
存一个数据seesionstorage.info = JSON.stringify({name:'aimee,company: 'duyi'});
存一组数据,转换为字符串形式
4.1.2 如何取出数据
localStrorage.name;
取一个数据JSON.parse(localStorage.info);
取一组数据,转换为对象形式seesionstorage.name;
取一个数据JSON.parse(seesionstorage.info);
取一组数据,转换为对象形式
4.1.3 存储的有效期
localStorage ==> 永久的,除非手动删除
sessionStorage ==> 临时的,窗口关闭就没有了
4.1.4 作用域
- localStorage ==> 文档源限制(同源限制)
- sessionStorage ==> 文档源限制(同源限制) + 窗口
4.1.5 API
setItem(name,val)
:设置属性值getItem(name)
:获得属性值removeItem(name)
:移除属性clear()
:清除所有属性
4.2 cookie
不开启服务器也可以用
存储信息到用户的设备上,数据量较小
navigator.cookieEnabled
,检测是否启用了 cookie
4.2.1 设置 cookie 值
document.cookie = "name=aimee";
每次只能设置一个值,因为浏览器会认为后面的键值对是这个cookie的属性
4.2.2 获得 cookie 值
- document.cookie:获取所有 cookie 值,需要自己封装方法获取个别 cookie 值
console.log(document.cookie);
不建议出现分号,逗号,空格的奇怪的符号,需要转义
- encodeURIComponent():存入 cookie 时,把特殊字符转义
document.cookie = "name=" + encodeURIComponent('aim;ee');
- decodeURIComponent():获取 cookie 时,解码
console.log(decodeURIComponent(document.cookie));
/*** 封装 getCookie 方法* @param {*} name * @returns */
function getCookie(name) {var name = name + "=";var ca = document.cookie.split(';');for(var i = 0; i < ca.length; i++) {var c = ca[i];while (c.charAt(0)==' ') c = c.substring(1);if (c.indexOf(name) != -1) return c.substring(name.length, c.length);}return "";
}
document.cookie = "name=scott";
document.cookie = "age=1000";
console.log(document.cookie);
console.log(getCookie('name'));
4.2.3 设置 cookie 存储期限
不设置时间默认为 session
- max-age 设置时间段,单位:秒
document.cookie = "name=scott;max-age=1000";
- expires 当前时间加上保存时间
// 设置为北京时间,保存时间为三天
var oDate = new Date();
oDate.setDate(oDate.getDate() + 3);
document.cookie = "name=aimee;expires=" + oDate;// 设置为格林威治时间,保存时间为 10000s
var timestamp = (new Date()).getTime() + 10000;
var expires = new Date(timestamp).toGMTString();
document.cookie = "name=scott;expires=" + expires;
4.2.4 domain
域名,要使两个 cookie 可以相互访问,可将 domain 设为同一个域名
4.2.5 path
cookie 设置的路径
4.2.6 删除 cookie
- 设置 max-age=0,需要带上键值对
document.cookie = 'name=scott;max-age=0';
- 设置 expires 为之前的时间
document.cookie = 'name=scott;expires= …';
05 history
- history.back():回退
- history.forward():前进
- history.go(n)
- SPA
5.1 通过修改 hash 和 hashchange 事件来实现历史纪录管理
pushState,
history.pushState(state, title, url);
添加一条历史记录replaceState,
history.replaceState(state, title, url);
替换当前的历史记录
5.1.1 参数
state:一个与指定网址相关的状态对象,popstate 事件触发时,该对象会传入回调函数中。如果不需要这个对象,此处可以填 null
title:新页面的标题,但是所有浏览器目前都忽略这个值,因此这里可以填 null
url:新的网址,必须与当前页面处在同一个域。浏览器的地址栏将显示这个网址
5.1.2 事件
- popstate 事件:历史记录发生改变时触发
- 调用 history.pushState() 或者 history.replaceState() 不会触发 popstate 事件
- hashchange 事件:当页面的 hash 值改变的时候触发,常用于构建单页面应用
06 Worker
worker 可以开启分线程
var worker = new Worker('worker.js');
worker 文件必须和主文件满足同源策略
6.1 worker 和主线程之间的通信
- postMessage(n) 方法:允许来自不同源的脚本采用异步方式进行有限的通信,可以实现跨文本档、多窗口、跨域消息传递
- message 事件:响应 postMessage(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>demo04</title>
</head>
<body><script>var worker = new Worker('./worker.js');worker.postMessage(10);worker.onmessage = function (e) {console.log(e.data);}</script>
</body>
</html>
onmessage = function (e) {var num = e.data;for(var i = 0; i < 1000000000; i++){num += 1;}this.postMessage(num);
}
6.2 结束一个 worker
- close():worker 自己关掉,在 worker 作用域中调用(worker.js 里面
close();
) - terminate():主进程里面关掉 worker,在 worker 对象上调用(主进程的 worker 对象上
worker.terminate();
)
6.3 其他特性
importScripts('./math1.js','./math2.js')
worker 只是 window 的子集,只能实现部分功能,不能获取到window.document
,所以这里不要引 juery,zepto。可以引入一些计算类的库- 作用域 globalWorkerScope
- 可以继续生成 worker 对象(暂时还不支持)
- navigator
- XMLHttpRequest
- setTimeout / serInterval
07 多媒体 — audio 和 video
7.1 标签属性
- 和设置 weight 和 height
- autoplay:自动播放
- controls:设置控件
- preload:预加载
- none:默认值,不需要预加载
- metadata:元数据,诸如时长、比特率、帧大小这样的原数据而不是媒体内容需要加载的
- auto:浏览器应当加载它认为适量的媒体内容
- loop:是否循环播放音频/视频
- poster:video独有,当视频不可用或未开始播放时,使用一张图片替代,否则是空白
- 多类型资源
<audio id="music"><source src="happy.mp3" type="audio/mpeg"><source src="happy.ogg" type="audio/ogg"></audio>
<!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>demo06</title>
</head>
<body><audio id="music"><source src="happy.mp3" type="audio/mpeg"><source src="happy.ogg" type="audio/ogg"></audio>
</body>
</html>
7.2 脚本化
7.2.1 创建 audio/video 对象
var audio = doxument.getElementById('audio');
var audio = new Audio(./happy.mp3);
var audio = doxument.createElement('video');
7.2.2 设置属性
controls:控制条
audio.controls = true;
autoplay:自动播放
audio.autoplay = true;
loop:循环播放
audio.loop = true;
preload:预加载
audio.preload = 'auto';
volume:音量
- 表示播放音量,介于0(静音)~1(最大音量)之间,默认1。将 muted 属性设置为 true 则会进入静音模式,设置为 false 则会恢复之前指定的音量继续播放
- 超过范围会报错(0-1)
playbackRate:播放速率
- 用于指定媒体播放的速度。该属性值为 1.0 表示正常速度,大于1则表示快进,0-1之间表示慢放,负值表示回放
- 每个浏览器实现的会有差别,具体看浏览器实现
currentSrc:返回资源链接,媒体数据的 url 地址
console.log(audio.currentSrc);
- 注意
windows.onload
currentTime:设置或返回音频/视频播放的当前位置
- 注意
windows.onload
duration:返回当前音频/视频的时长,单位为秒
- 注意
windows.onload
played/buffered/seekable
- played:返回已经播放(看过)的时间段
- buffered:返回当前已经缓冲的时间段
- seekable:返回用户可以跳转的时间段
- 这三个属性都是 TimeRanges 对象,每个对象都有一个 length 属性以及 start() 和 end() 方法
- length:表示当前的一个时间段
- start() 与 end():返回当前时间段的起始时间点和结束时间点(单位是秒,起始参数是0)
- 下面代码确定当前缓存内容的百分比:
var percent_loaded = Math.floor(song.buffered.end(0) / song.duration*100);
paused/seeking/ended:这三个属性用来查询媒体播放状态
- paused 为 true 表示播放器暂停
- seeking 为 true 表示播放器正在调到一个新的播放点
- 如果播放器播放完媒体并且停下来,则 ended 属性为 true
readyState:表示音频元素的就绪状态
0 = HAVE_NOTHING:没有关于音频是否就绪的信息
1 = HAVE_METADATA:关于音频就绪的元数据
2 = HAVE_CURRENT_DATA:关于当前播放位置的数据是可用的,但没有足够的数据来播放下一帧/毫秒
3 = HAVE_FUTURE_DATA:当前及至少下一帧的数据是可用的
4 = HAVE_ENOUGH_DATA:可用数据足以开始播放
networkState:表示音频元素的当前网络状态
- 0 = NETWORK_EMPTY:音频尚未初始化
- 1 = NETWORK_IDLE:音频是活动的且已选取资源,但并未使用网络
- 2 = NETWORK_LOADING:浏览器正在下载数据
- 3 = NETWORK_NO_SOURCE:未找到音频来源
error:MediaError 对象的 code 属性返回一个数字值,它表示音频的错误状态
- 1 = MEDIA_ERR_ABORTED:取回过程被用户中止
- 2 = MEDIA_ERR_NETWORK:当下载时发生错误
- 3 = MEDIA_ERR_DECODE:当解码时发生错误
- 4 = MEDIA_ERR_SRC_NOT_SUPPORTED:不支持音频/视频
<!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>demo06</title>
</head>
<body><audio id="audio" src=""></audio><script>var audio = document.getElementById('audio');audio.src = './happy.mp3';audio.controls = true;audio.autoplay = true;audio.loop = true;audio.preload = 'auto';</script>
</body>
</html>
<!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>demo06</title>
</head>
<body><script>var audio = new Audio('./happy.mp3');document.body.appendChild(audio);audio.controls = true;audio.autoplay = true;audio.loop = true;audio.preload = 'auto';</script>
</body>
</html>
7.2.3 方法
- play():播放视频/音频元素
- pause():暂停视频/音频元素
- load():重新加载视频/音频元素,用于在更改来源或其他设置后对音频/视频元素进行更新
- canPlayType():音频/视频格式是否支持
7.2.4 事件
- play:开始播放触发
- pause:暂停触发
- loadedmetadata:浏览器获取完媒体的元数据触发
- loaddeddata:浏览器已经加载完当前帧数据,准备播放时触发
- ended:当前播放结束后触发
<!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>demo06</title>
</head>
<body><button id="play">play</button><button id="pause">pause</button><button id="load">load</button><button id="down">-</button><button id="up">+</button><button id="slow"><<</button><button id="quick">>></button><button id="more">more</button><button id="both">both</button><br><br><script>var audio = new Audio('./happy.mp3');document.body.appendChild(audio);audio.controls = true;var play = document.getElementById('play');var pause = document.getElementById('pause');var load = document.getElementById('load');var down = document.getElementById('down');var up = document.getElementById('load');var slow = document.getElementById('slow');var quick = document.getElementById('quick');var more = document.getElementById('more');var both = document.getElementById('both');play.onclick = function () {audio.play();}pause.onclick = function () {audio.pause();}load.onclick = function () {audio.load();}down.onclick = function () {if(audio.volume > 0.1){audio.volume -= 0.1;}}up.onclick = function () {audio.volume += 0.1;}quick.onclick = function () {audio.playbackRate += 0.1;}slow.onclick = function () {audio.playbackRate -= 0.1;}more.onclick = function () {console.log(audio.played);}both.onclick = function () {if(audio.pause){audio.play();}else{audio.pause();}}</script>
</body>
</html>
08 geolocation 对象
8.1 查看 geolocation 对象
- window.navigator.geolocation 对象:查看 geolocation 对象
8.2 getCurrentPosition()
- getCurrentPosition(s, e, p): 获取当前的位置信息
- success:成功的回调(必须)
- error:失败的回调
- options:参数
- 需要翻墙
- Geoposition:成功获取位置时返回的对象
- latitude:纬度
- longitude:经度
- altitude:海拔
- accuracy:定位精准度,单位 m
- altitudeAccuracy:海拔精准度,单位 m
- heading:方向
- speed:速度
- https://dev.w3.org/geo/api/spec-source.html#coordinates_interface
PositionError:获取位置失败时返回的对象
- 用户拒绝 code = 1
- 获取不到 code = 2
- 连接超时 code = 3
- https://dev.w3.org/geo/api/spec-source.html#position_error_interface
options 配置参数
- enableHighAccuracy:是否需要高精度位置默认 false
- timeout:单位ms,请求超时时间 默认 infinity
- maximumAge:单位ms,位置信息过期时间,设置为 0 就无条件获取新的地理位置信息,默认0
- https://dev.w3.org/geo/api/spec-source.html#position_options_interface
<!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>demo07</title>
</head>
<body>222<script>var options = {enableHighAccuracy: true,timeout: 8000}// 特别注意,需要在连上vpn的时候才能获取到function s(e) {console.log('success');console.log(e);}function e(e) {console.log('error');console.log(e);}navigator.geolocation.getCurrentPosition(s, e, options);</script>
</body>
</html>
8.3 watchPosition()
- watchPosition():用于注册监听器,在设备的地理位置发生改变的时候自动被调用
var id = geolocation.watchPosition()
- 参数与 getCurrentPosition 相同
8.4 clearWatch()
- clearWatch(id):使用 clearWatch 清除监听
09 devicemotion 对象
devicemotion 主要用于移动端
window.addEventListener('devicemotion', function(e){console.log(e);
});
均为只读属性:
- accelerationIncludingGravity:(包括重心引力)重力加速度
- acceleration:(需要陀螺仪支持)重力加速度
- rotationRate(alpha, beta, gamma):旋转速率
- interval:获取的时间间隔
<!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>demo07</title>
</head>
<body><div id="container"></div><script>// 演示获取运动加速度var c = document.getElementById('container');window.addEventListener('devicemotion', function (e) {console.log(e);var h = c.innerHTML + e.accelerationIncludingGravity.x + '-' + e.accelerationIncludingGravity.y + '-' + e.accelerationIncludingGravity.z + '<br>';c.innerHTML = h;})</script>
</body>
</html>
10 drag & drop
- 常用于各种拖动操作中
- 创建可拖动元素
<div draggable="true"></div>
10.1 拖拽相关事件
- dragstart:被拖拽元素,开始被拖拽时触发
e.dataTransfer.setData("data", e.target.id)
- dragend:被拖拽元素,拖拽完成时触发
- dragenter:目标元素,拖拽元素进入目标元素
- dragover:目标元素,拖拽元素在目标元素上移动
- drop:目标元素,被拖拽元素在目标元素上同时鼠标放开触发的事件
e.dataTransfer.getData("data")
- 需要阻止 dragover 的默认行为才会触发 drop 事件
10.2 DragEvent 事件对象
- 传值
e.dataTransfer.setData("data", e.target.id)
- 取值
e.dataTransfer.getData("data")
<!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>demo08</title><style>#drag{width: 100px;height: 100px;background: #000;}#box{height: 300px;width: 300px;border: 2px solid #000;}</style>
</head>
<body><div id="drag" draggable="true"></div><br><div id="box"></div><script>var drag = document.getElementById('drag');var box = document.getElementById('box');drag.addEventListener('dragstart', function (e) {console.log('dragstart');e.dataTransfer.setData("data", 111);});drag.addEventListener('dragend', function () {console.log('dragend');});box.addEventListener('dragenter', function () {console.log('dragenter');});box.addEventListener('dragover', function (e) {console.log('dragover');e.preventDefault();});box.addEventListener('drop', function (e) {console.log('drop');console.log(e);console.log(e.dataTransfer.getData("data"));});</script>
</body>
</html>
<!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>demo08</title><style>#drag1{width: 100px;height: 100px;background: #000;}#drag2{width: 100px;height: 100px;background: #00f;}#box{height: 300px;width: 300px;border: 2px solid #000;}</style>
</head>
<body><div id="drag1" draggable="true"></div><div id="drag2" draggable="true"></div><br><div id="box"></div><script>var drag1 = document.getElementById('drag1');var drag2 = document.getElementById('drag2');var box = document.getElementById('box');drag1.addEventListener('dragstart', function (e) {e.dataTransfer.setData("data", 1);});drag2.addEventListener('dragstart', function (e) {e.dataTransfer.setData("data", 2);});box.addEventListener('dragover', function (e) {e.preventDefault();});box.addEventListener('drop', function (e) {var num = e.dataTransfer.getData("data");console.log(num);if(num == 1){box.appendChild(drag1);}else{box.appendChild(drag2);}});</script>
</body>
</html>
11 FileReader 构造函数
https://blog.csdn.net/weixin_44116302/article/details/91554835
11.1 FileReader 方法
- abort():终止读取
- 通过不同的方式读取文件:
- readAsText(file, [encoding]):将文件读取为文本,常用
- readAsBinaryString(file):将文件读取为二进制编码
- readAsDataURL(file):将文件读取为 DataURL 编码
- readAsArrayBuffer(file):将文件读取为 arraybuffer
11.2 FileReader 事件
- onloadstart:读取文件开始时触发
- onprogress:读取过程中触发,会返还本次读取文件的最大字节数和已经读取完毕的字节数,可以用来做进度条
- onload:读取完成时触发
- onloadend:读取结束后触发,不论成功还是失败都会触发,触发时机在 onload 之后
- onabort:读取中断时触发
- onerror:读取文件失败时触发
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Document</title>
</head>
<body><form><fieldset><legend>分步读取文件:</legend><input type="file" id="File"><input type="button" value="中断" id="Abort"><p><lable>读取进度:</lable><progress id="Progress" value="0" max="100"></progress></p></fieldset></form><script src="./loadFile.js"></script><script>var progress = document.getElementById('Progress');var events = {load: function () {console.log('loaded');},progress: function (percent) {progress.value = percent;},success: function () {console.log('success');}};var loader;// 选择好要上传的文件后触发onchange事件document.getElementById('File').onchange = function () {var file = this.files[0];console.log(this.files)console.log(file);//loadFile.jsloader = new FileLoader(file, events);};document.getElementById('Abort').onclick = function () {loader.abort();}</script>
</body>
</html>
/*
* 文件读取模块
* file 文件对象
* events 事件回掉对象 包含 success , load, progress
*/
var FileLoader = function (file, events) {this.reader = new FileReader();this.file = file;this.loaded = 0;this.total = file.size;//每次读取1Mthis.step = 1024 * 1024;this.events = events || {};//读取第一块this.readBlob(0);this.bindEvent();
}FileLoader.prototype = {bindEvent: function (events) {var _this = this,reader = this.reader;reader.onload = function (e) {_this.onLoad();};reader.onprogress = function (e) {_this.onProgress(e.loaded);};// start 、abort、error 回调暂时不加},// progress 事件回掉onProgress: function (loaded) {var percent,handler = this.events.progress;this.loaded += loaded;percent = (this.loaded / this.total) * 100;handler && handler(percent);},// 读取结束(每一次执行read结束时调用,并非整体)onLoad: function () {var handler = this.events.load;// 应该在这里发送读取的数据handler && handler(this.reader.result);// 如果未读取完毕继续读取if (this.loaded < this.total) {this.readBlob(this.loaded);} else {// 读取完毕this.loaded = this.total;// 如果有success回掉则执行this.events.success && this.events.success();}},// 读取文件内容readBlob: function (start) {var blob,file = this.file;// 如果支持 slice 方法,那么分步读取,不支持的话一次读取if (file.slice) {blob = file.slice(start, start + this.step);} else {blob = file;}this.reader.readAsText(blob);},// 中止读取abort: function () {var reader = this.reader;if(reader) {reader.abort();}}
}
12 WebSocket
- WebSocket 对象提供了一组APl,用于创建和管理 webSocket 连接,以及通过连接发送和接收数据
- Websocket 其实是一个新协议,跟 HTTP 协议基本没有关系,只是为了兼容现有浏览器的握手规范而己,借用了HTTP的协议来完成握手
- WebSocket 提供了一个专门用来测试 WebSocket 的服务器 — ws://echo.websocket.org
- ws 相当于 http,wss 相当于 https
- 产生原因
- 在 HTTP/1.0 中,大多实现为每个请求/响应交换使用新的连接
- 在 HTTP/1.1 中 一个连接可用于一次或多次请求/响应交换
- HTTP 协议中,服务端不能主动联系客户端,只能有客户端发起
- webSoket 服务器和客户端均可主动发送数据
12.1 建立连接的握手
- 当 web 应用程序调用 new WebSocket(url) 接口时,Browser 就开始了与地址为 url 的 WebServer 建立握手连接的过程
- Browser 与 WebSocket 服务器通过 TCP 握手建立连接,如果这个建立连接失败,那么后面的过程就不会执行,Web 应用程序将收到错误消息通知
- 在 TCP 建立连接成功后,Browser 通过 http 协议传送 WebSocket 支持的版本号,协议的字版本号,原始地址,主机地址等等一些列字段给服务器端
- WebSocket服务器收到 Browser 发送来的请求后,如果数据包数据和格式正确,客户端和服务器端的协议版本号匹配等等,就接受本次握手连接,并给出相应的数据回复,同样回复的数据包也是采用 http 协议传输
- Browser 收到服务器回复的数据包后,如果数据包内容、格式都没有问题的话,就表示本次连接成功,触发 onopen 消息,此时 web 开发者就可以在此时通过 send 接口向服务器发送数据。否则,握手连接失败,Web 应用程序会收到 onerror 消息,并且能知道连接失败的原因
12.2 HTTP 三次握手
- 第一次握手:建立连接时,客户端 A 发送 SYN 包(SYN = j)到服务器 B,并进入 SYN_SEND 状态,等待服务器 B 确认
- 第二次握手:服务器 B 收到 SYN 包,必须确认客户 A 的 SYN(ACK = j + 1),同时自己也发送一个 SYN 包(SYN = k),即 SYN + ACK 包,此时服务器 B 进入 SYN_RECV 状态
- 第三次握手:客户端 A 收到服务器 B 的 SYN+ACK 包,向服务器 B 发送确认包 ACK(ACK = k + 1),此包发送完毕,客户端 A 和服务器 B 进入 ESTABLISHED 状态,完成三次握手
- 完成三次握手,客户端与服务器开始传送数据
12.3 创建 WebSocket
var Socket = new WebSocket;
12.4 WebSocket 方法
- Socket.send():send(data) 方法使用连接传输数据
- Socket.close():close() 方法用于终止任何现有的连接
12.5 WebSocket 事件
事件 | 事件处理程序 | 描述 |
---|---|---|
open | Socket.onopen | 建立 socket 连接时触发这个事件 |
message | Socket.onmessage | 客户端从服务器接收数据时触发 |
error | Socket.onerror | 连接发生错误时触发 |
close | Socket.onclose | 连接关闭时触发 |
<!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>demo10</title>
</head>
<body><script>var socket = new WebSocket('ws://localhost:8888');socket.onopen = function () {console.log('open');socket.send('hello');}socket.onmessage = function (e) {console.log('message');console.log(e);console.log(e.data);socket.close();}socket.onclose = function () {console.log('close');}socket.onerror = function () {console.log('error');}</script>
</body>
</html>
12.6 WebSocket 的优点
- 客户端与服务器都可以主动传送数据给对方
- 不用频率创建 TCP 请求及销毁请求,减少网络带宽资源的占用,同时也节省服务器资源
【HTML5 笔记】基础内容相关推荐
- html5+css3基础内容
3.网页开发工具 3.1文档类型声明标签 <!doctype>文档声明,作用就是告诉浏览器使用哪种html版本来显示网页. <!doctype html> 这句代码的意思是:当 ...
- SQL学习笔记---基础内容
count函数不可用于where子句中 1.查找薪水涨幅超过15次的员工号以及其对应的涨幅次数 select emp_no , count(*) as t from salaries group by ...
- 初学Oracle的笔记(2)——基础内容(实时更新中..)
续 初学Oracle的笔记(1)--基础内容(实时更新中..) 1.oracle中创建一张表,写法与sql server中的一样. SQL> create table Course 2 ( cn ...
- 【转】医疗业务学习笔记--DICOM协议的基础内容!!!!!!!!!!
转自:医疗业务学习笔记--DICOM协议的基础内容 - 知乎 本文首发于"雨夜随笔"公众号,欢迎关注. DICOM协议是医疗领域对如何处理.存储.打印和传输医疗图片的一系列标准.D ...
- input内容右对齐_STM32学习笔记—DAC基础内容及常见问题
DAC,Digital-to-Analog Converter(数模转换器),DA转换和AD转换有着同样重要的作用,在许多场合都能看到DAC的应用. 今天是第8篇分享,<STM32学习笔记> ...
- 数字图像处理笔记(一)基础内容
基础内容 数字图像是什么,和模拟图像又有什么区别 数字图像处理 数字图像处理研究内容 数字图像处理有哪些方法 计算机图形学和数字图像处理的区别 常用的数字图像处理开发工具 数字图像 图像的数学表达 数 ...
- Python学习笔记 1.0 基础内容篇章
Python学习笔记 1.0 基础内容篇章 注释 变量 一.定义变量 二.使用变量 bug和debug bug: Debug工具: 数据类型 认识数据类型 在定义数据类型时发生的错误: 数据类型的补表 ...
- SpringBoot学习笔记一:基础内容
文章目录 SpringBoot基础内容 SpringBoot概述 SpringBoot功能 SpringBoot快速入门 需求 实现步骤 总结 SpringBoot项目快速构建 SpringBoot起 ...
- 哪一个不是html5新增的语义化标记元素,东师19春《HTML5开发基础与应用》作业考核【标准答案】...
<HTML5开发基础与应用>作业考核-0001 试卷总分:100 得分:0 一. 单选题 (共 30 道试题,共 60 分) 1.关于cookie存储机制下列说法不正确的是: A.简 ...
- Spring Boot学习笔记-基础(2)
Spring Boot学习笔记-基础(2) Spring Boot 优点: – 快速创建独立运行的Spring项目以及与主流框架集成 – 使用嵌入式的Servlet容器,应用无需打成WAR包 – st ...
最新文章
- vim学习笔记(四)
- :x 和 :wq 的区别
- python挖坑法实现快排
- 高一学生计算机知识现状分析,关于高中信息技术课教学现状的思考
- 一个数如果刚好与它所有的真因子之和相等,则称该数为一个“完数
- 欧几里德算法(求最大公约数和最小公倍数)
- 获取电信光猫天翼网关 3.0超级管理员密码,桥接模式,让网速上一个档次
- Linux下安装PyQt4
- 【OpenCV】—ROI区域图像叠加图像混合
- 好文:读客图书董事长华楠接受采访
- 加速 Android 开发的五大开源网站
- opencv保存设像头图片时调整白平衡功能
- css:flex布局子元素宽度被压缩问题
- Spring实现`aop`过程
- 软件需求说明及对应的测试用例,测试用例与需求的对应关系 - Mr.南柯 - 51Testing软件测试网 51Testing软件测试网-软件测试人的精神家园...
- 计算机专业用什么轴的键盘,机械键盘的哪个轴适合办公室使用
- Kafka3.0 提交offset方式
- 【人工智能 卷积神经网络】基础练习:基于torch构建卷积神经网络,测试集正确率达 百分之99
- 高数值孔径图形图案扩散器的设计与优化
- A、B、C三类IP地址的最大网络数和每个网络中的最大主机数
热门文章
- 【技术】基于angularJS的前端自动化测试工具Protractor快速入门
- dijkstra最短路径算法视频_单源最短路径(1):Dijkstra 算法
- windows访问控制列表ACL
- pytorch基于yolo目标检测的智慧课堂系统
- 慧荣SM2269XT量产开卡成功,附SM2269XT量产工具、开卡软件
- Linux后端开发-POSIX标准以及shell编程
- SpringCloud【框架】
- 电脑怎么连接两个以上的显示器
- (亲测可用)修改VisualSVN Server地址为ip地址,修改svn服务端地址为ip或者域名地址的方法
- 冲激响应不变法或双线性变换法中的参数T为什么是一个无关紧要的参数