文章目录

  • 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');
<!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),半径为 r2
  • addColorStop(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'; 线条的结束端点样式,默认为 butt
  • lineJoin = 'bevel|round|miter'; 两条线相交时,所创建的拐角类型,默认为 miter
  • lineWidth 线条宽度
  • 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" />
    • 绝对坐标和相对坐标
  • 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 笔记】基础内容相关推荐

  1. html5+css3基础内容

    3.网页开发工具 3.1文档类型声明标签 <!doctype>文档声明,作用就是告诉浏览器使用哪种html版本来显示网页. <!doctype html> 这句代码的意思是:当 ...

  2. SQL学习笔记---基础内容

    count函数不可用于where子句中 1.查找薪水涨幅超过15次的员工号以及其对应的涨幅次数 select emp_no , count(*) as t from salaries group by ...

  3. 初学Oracle的笔记(2)——基础内容(实时更新中..)

    续 初学Oracle的笔记(1)--基础内容(实时更新中..) 1.oracle中创建一张表,写法与sql server中的一样. SQL> create table Course 2 ( cn ...

  4. 【转】医疗业务学习笔记--DICOM协议的基础内容!!!!!!!!!!

    转自:医疗业务学习笔记--DICOM协议的基础内容 - 知乎 本文首发于"雨夜随笔"公众号,欢迎关注. DICOM协议是医疗领域对如何处理.存储.打印和传输医疗图片的一系列标准.D ...

  5. input内容右对齐_STM32学习笔记—DAC基础内容及常见问题

    DAC,Digital-to-Analog Converter(数模转换器),DA转换和AD转换有着同样重要的作用,在许多场合都能看到DAC的应用. 今天是第8篇分享,<STM32学习笔记> ...

  6. 数字图像处理笔记(一)基础内容

    基础内容 数字图像是什么,和模拟图像又有什么区别 数字图像处理 数字图像处理研究内容 数字图像处理有哪些方法 计算机图形学和数字图像处理的区别 常用的数字图像处理开发工具 数字图像 图像的数学表达 数 ...

  7. Python学习笔记 1.0 基础内容篇章

    Python学习笔记 1.0 基础内容篇章 注释 变量 一.定义变量 二.使用变量 bug和debug bug: Debug工具: 数据类型 认识数据类型 在定义数据类型时发生的错误: 数据类型的补表 ...

  8. SpringBoot学习笔记一:基础内容

    文章目录 SpringBoot基础内容 SpringBoot概述 SpringBoot功能 SpringBoot快速入门 需求 实现步骤 总结 SpringBoot项目快速构建 SpringBoot起 ...

  9. 哪一个不是html5新增的语义化标记元素,东师19春《HTML5开发基础与应用》作业考核【标准答案】...

    <HTML5开发基础与应用>作业考核-0001 试卷总分:100    得分:0 一. 单选题 (共 30 道试题,共 60 分) 1.关于cookie存储机制下列说法不正确的是: A.简 ...

  10. Spring Boot学习笔记-基础(2)

    Spring Boot学习笔记-基础(2) Spring Boot 优点: – 快速创建独立运行的Spring项目以及与主流框架集成 – 使用嵌入式的Servlet容器,应用无需打成WAR包 – st ...

最新文章

  1. vim学习笔记(四)
  2. :x 和 :wq 的区别
  3. python挖坑法实现快排
  4. 高一学生计算机知识现状分析,关于高中信息技术课教学现状的思考
  5. 一个数如果刚好与它所有的真因子之和相等,则称该数为一个“完数
  6. 欧几里德算法(求最大公约数和最小公倍数)
  7. 获取电信光猫天翼网关 3.0超级管理员密码,桥接模式,让网速上一个档次
  8. Linux下安装PyQt4
  9. 【OpenCV】—ROI区域图像叠加图像混合
  10. 好文:读客图书董事长华楠接受采访
  11. 加速 Android 开发的五大开源网站
  12. opencv保存设像头图片时调整白平衡功能
  13. css:flex布局子元素宽度被压缩问题
  14. Spring实现`aop`过程
  15. 软件需求说明及对应的测试用例,测试用例与需求的对应关系 - Mr.南柯 - 51Testing软件测试网 51Testing软件测试网-软件测试人的精神家园...
  16. 计算机专业用什么轴的键盘,机械键盘的哪个轴适合办公室使用
  17. Kafka3.0 提交offset方式
  18. 【人工智能 卷积神经网络】基础练习:基于torch构建卷积神经网络,测试集正确率达 百分之99
  19. 高数值孔径图形图案扩散器的设计与优化
  20. A、B、C三类IP地址的最大网络数和每个网络中的最大主机数

热门文章

  1. 【技术】基于angularJS的前端自动化测试工具Protractor快速入门
  2. dijkstra最短路径算法视频_单源最短路径(1):Dijkstra 算法
  3. windows访问控制列表ACL
  4. pytorch基于yolo目标检测的智慧课堂系统
  5. 慧荣SM2269XT量产开卡成功,附SM2269XT量产工具、开卡软件
  6. Linux后端开发-POSIX标准以及shell编程
  7. SpringCloud【框架】
  8. 电脑怎么连接两个以上的显示器
  9. (亲测可用)修改VisualSVN Server地址为ip地址,修改svn服务端地址为ip或者域名地址的方法
  10. 冲激响应不变法或双线性变换法中的参数T为什么是一个无关紧要的参数