系统化学习前端之HTML(HTML5)
写在前面
前面已经梳理了HTML的基础标签使用,常规开发的话,基础标签已经完全满足日常工作了。但是,我们往往不满足于简单的页面,还需要提升,这个提升包括了页面SEO的提升、页面内容的提升以及页面交互的提升等等,语义化、canvas、音视频等特性也随之被催生出来。
语义化
语义化被提出,最重要的目的是提高页面的SEO。搜索引擎排名对目前的电商类网站有着举足轻重的地位,前端开发也开始规范化,定义标签不再清一色div和span嵌套了。
H5语义化标签
<header></header>
定义文档的页眉;
<footer></footer>
定义文档的页脚;
<nav></nav>
定义导航链接部分;
<section></section>
定义文档区块;
<article></article>
定义文档内容;
<aside></aside>
定义侧边栏部分;
<figure></figure>
定义独立区块,相对于原有div区块有缩进;
<figcaption></figcaption>
定义独立区块的标题,与figure配合使用;
<details></details>
定义关联内容描述,标题可折叠;
<summary></summary>
定义关联内容描述的标题,与detail配合使用;
点击查看代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>HTML5</title>
</head>
<body>
<div>
<div>figure</div>
<figure>
<figcaption>title</figcaption>
content: All the growth is a leap in the dark.
</figure>
<div>figure</div>
</div>
<div>
<div>details</div>
<details>
<summary>标题</summary>
content: All the growth is a leap in the dark.
</details>
<div>details</div>
</div>
</body>
</html>
注意:部分语义化标签与原有标签的功能一致,只是标签名不同。
增强表单
输入列表
<datalist></datalist>
本身不可见,为input标签提供输入建议,用户可从列表中选取输入,datalist与input通过id关联,具体用法如下:
点击查看代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>HTML5</title>
</head>
<body>
<datalist id="river">
<option>长江</option>
<option>嘉陵江</option>
<option>金沙江</option>
<option>黑龙江</option>
</datalist>
<input type="text" list="river">
</body>
</html>
进度条
<progress value="10" max="100"></progress>
进度条控件,通过value属性指定进度,通过max定义最大范围;
刻度尺
<meter min="0" max="100" low="10" high="60" optimum="90" value="70"></meter>
用于标示一个值所处范围:判定value是否合适:value在min-low范围内为不可接受(红色),value在low-hight范围内为可以接受(黄色),value在high-max范围内为非常优秀(绿色);
输出
<output></output>
语义标签,无任何样式,相当于span,用法:<output>输出</output>
。
音视频
音频
音频标签使用如下:
<audio>
<source src="xxx/xxx.mp3">
<source src="xxx/xxx.wav">
<source src="xxx/xxx.webm">
浏览器版本太低,无法播放音频。
</audio>
注意:audio标签默认生成300*32的inline-block,播放按照source源顺序执行,一旦成功播放,不执行后续,当所有音频无法播放,提示:浏览器版本太低,无法播放音频。
-
audio标签属性:
-
autoplay
自动播放,默认为false; -
controls
是否显示播放控件,默认为false; -
loop
循环播放,默认为false; -
muted
静音,默认为fasle; -
preload
音频的预加载策略;属性有:auto(预加载音频的元数据(部分画面)及缓冲一定时长视频,默认为auto),metadate(预加载音频的元数据),none(不预加载任何数据)
-
-
audio-DOM对象
可以通过dom操作获取audioDOM对象;
-
属性
-
currentTime:当前播放时长;
-
duration:总时长;
-
paused:当前音频是否处于暂停状态;
-
volumn:当前音量,属性值为数字,范围(0-1);
-
playbackRate:播放速率,默认值为1,正常播放;
-
muted: 是否静音;
-
-
方法
-
play() 播放;
-
pause() 暂停;
-
-
事件
-
onplay:当前音频开始播放触发的事件;
-
onpause:当前音频暂停播放触发的事件;
-
-
视频
视频标签使用如下:
<video>
<source src="xxx/xxx.mp4">
<source src="xxx/xxx.ogg">
<source src="xxx/xxx.webm">
浏览器版本太低,无法播放视频。
</video>
注意:video标签默认生成300*150的inline-block,播放按照source源顺序执行,一旦成功播放,不执行后续,当所有视频无法播放,提示:浏览器版本太低,无法播放视频。
-
video标签属性:
-
autoplay
自动播放,默认为false; -
controls
是否显示播放控件,默认为false; -
loop
循环播放,默认为false; -
muted
静音,默认为fasle; -
preload
音频的预加载策略;属性有:auto(预加载音频的元数据(部分画面)及缓冲一定时长视频,默认为auto),metadate(预加载音频的元数据),none(不预加载任何数据) -
poster
播放前显示海报<video poster="xxx/xxx.png"></video>
;
-
-
video-DOM对象
可以通过dom操作获取videoDOM对象;
-
属性
-
currentTime:当前播放时长;
-
duration:总时长;
-
paused:当前视频是否处于暂停状态;
-
volumn:当前音量,属性值为数字,范围(0-1);
-
playbackRate:播放速率,默认值为1,正常播放;
-
muted: 是否静音;
-
-
方法
-
play() 播放;
-
pause() 暂停;
-
-
事件
-
onplay:当前视频开始播放触发的事件;
-
onpause:当前视频暂停播放触发的事件;
-
-
Canvas
Canvas 是 HTML5 提出的绘图 API,绘制图形为位图。Canvas 的出现使得网页在不依赖图片(资源开销较大)的情况下,可以绘制各种图案。
Canvas 本质是一个 300 * 150 (默认大小) 的 inline-block,我们也称之为画布。绘制图像需要通过与画布绑定且唯一的画笔对象,使用相应的 api 进行绘制。
基本用法
- HTML 中创建画布
<canvas width="400" height="400" id="c1"></canvas>
- JS 中获取画布,绑定画笔
var c1 = document.getElementById("c1");
var ctx = c1.getContext("2d"); // ctx 为画笔对象
- 通过 api 绘制图像
ctx.strokeStyle = "red";
ctx.strokeRect(10,10,100,100); // 坐标为(10, 10)的点处开始绘制宽高100的矩形
点击查看代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Canvas</title>
<style type="text/css">
#c1 {
width: 400px;
height: 400px;
border: 1px solid #ccc;
}
</style>
</head>
<body>
<!-- 分别注释 css 或者 canvas 宽高对比效果 -->
<canvas width="400" height="400" id="c1">您的浏览器不支持 canvas 标签。</canvas>
<script type="text/javascript">
var c1 = document.getElementById("c1");
var ctx = c1.getContext("2d");
ctx.strokeStyle = "red";
ctx.strokeRect(10,10,100,100)
</script>
</body>
</html>
注意:
- 画布的宽高需要使用 html 属性或者 js 指定,不能使用 css 设置,因为 css 的宽高和 画布实际宽高是不一致的。
- Canvas 作图是有坐标轴概念的,例如A点至B点画一条实线,需要A,B点坐标。因此,画布的左上角定为坐标原点,左右为x轴(右为正),上下为y轴(下为正)。
绘图API
点击查看代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Canvas</title>
<style type="text/css">
#c1 {
border: 1px solid #ccc;
}
</style>
</head>
<body>
<canvas width="400" height="400" id="c1"></canvas>
<script type="text/javascript">
var c1 = document.getElementById("c1");
var ctx = c1.getContext("2d");
// 可将绘制图形api 粘贴至此处观察效果。
</script>
</body>
</html>
-
绘制基本线条
- 绘制直线
ctx.beginPath(); ctx.moveTo(10,10); // 起始点(10,10) ctx.lineTo(100,10); // 终止点(100,10) ctx.stroke();
- 绘制二次曲线
ctx.beginPath(); ctx.moveTo(10,10); ctx.quadraticCurveTo(200,100,300,300); // 终止点(300,300),控制点(200,100) ctx.stroke();
- 绘制贝塞尔曲线
ctx.beginPath(); ctx.moveTo(10,10); ctx.bezierCurveTo(20,90,100,50,200,200); // 终止点(200,200),控制点1(20,90),控制点2(100,50) ctx.stroke();
- 绘制圆弧
ctx.beginPath(); // 以(100,100)为圆心,半径为50,起点0弧度,终点1.5π弧度,顺时针画圆弧 ctx.arc(100, 100, 50, 0, 2*Math.PI*0.75, false); ctx.stroke();
注意:arc()最后一个参数为Boolean类型,默认false表示顺时针,true表示逆时针,可缺省。
-
绘制简单形状
- 绘制圆形
ctx.beginPath(); ctx.arc(100, 100, 50, 0, 2*Math.PI); // 以(100,100)为圆心,半径为50,顺时针画圆 ctx.stroke();
- 绘制矩形
ctx.beginPath(); ctx.rect(40,40,100,100) ctx.stroke();
- 绘制三角形
ctx.beginPath(); ctx.moveTo(30,30); ctx.lineTo(150,150); ctx.lineTo(30,150); ctx.closePath(); // 闭合路径,使用直线连接起点和终点。 ctx.stroke();
- 绘制圆角矩形
ctx.beginPath(); ctx.moveTo(40,30); ctx.arcTo(130,30,130,130,10); // 控制点1(130,30),控制点2(130,130),半径为10 ctx.arcTo(130,130,30,130,10); ctx.arcTo(30,130,30,30,10); ctx.arcTo(30,30,130,30,10); ctx.stroke();
注意:arcTo()需要两个控制点绘制圆弧,具体使用可参照 MDN arcTo
-
绘制渐变
- 绘制线性渐变
var gradient = ctx.createLinearGradient(10,10,300,300); // 创建线性渐变对象,起点(10,10),终点(300,300) gradient.addColorStop(0, "blue"); // 设置比例及渐变色 gradient.addColorStop(0.5, "red"); gradient.addColorStop(1, "#0f0"); ctx.fillStyle = gradient; // 应用渐变色 ctx.fillRect(10,10,300,300); // 绘制图形
注意:canvas绘图有两种方式:fill() 填充 和 stroke() 描边,对应两种方式可以设置相应的属性 fillStyle 和 fillStyle。其他属性可参考 canvas 属性
- 绘制径向渐变
// 圆心为(160,160)生成半径30和100的圆,交集部分圆环为径向对象范围 var gradient = ctx.createRadialGradient(160,160,30,160,160,100); gradient.addColorStop(0, "blue"); gradient.addColorStop(0.5, "red"); gradient.addColorStop(1, "#0f0"); ctx.fillStyle = gradient; ctx.fillRect(10,10,300,300);
-
绘制特殊效果
- 绘制阴影效果
ctx.save(); // 保存当前画笔状态(无状态画笔) ctx.shadowBlur = 10; // 设置阴影模糊级数 ctx.shadowOffsetX = 20; // 设置阴影水平偏移,可设置负值。 ctx.shadowOffsetY = 20; // 设置阴影垂直偏移,可设置负值。 ctx.shadowColor = 'black'; // 设置阴影颜色,不可使用 #fff ctx.fillStyle = '#00f'; ctx.beginPath(); ctx.fillRect(20,20,100,100); ctx.restore(); // 恢复上一次save的画笔状态(无状态画笔),save 和 restore 之间的画笔是阴影画笔,可注释这行,查看效果 ctx.fillStyle = 'skyblue'; ctx.beginPath(); ctx.fillRect(150,20,100,100);
- 绘制透明效果
ctx.fillStyle = 'red'; ctx.fillRect(20,20,100,100); ctx.globalAlpha = 0.2; // 设置透明度alpha为0.2,范围 0 - 1 ctx.fillStyle = 'blue'; ctx.fillRect(60,60,100,100); ctx.fillStyle = 'green'; // 未使用 save 和 restore, green 使用了 blue的 alpha为0.2的画笔 ctx.fillRect(80,80,100,100);
-
绘制图像
- 放缩图像
var image = new Image(); //创建图片对象 image.src = "https://images.cnblogs.com/cnblogs_com/blogs/766345/galleries/2274688/o_230215035425_canvas.png"; image.onload = function () { ctx.drawImage(image, 10, 10, 200, 200) // 坐标(10,10)点处开始绘制图像,图像宽高 200*200,宽高可缺省,表示不放缩 }
注意:绘制图像一定要在图像加载完成以后,即onload触发以后。
- 裁剪图像
var image = new Image(); image.src = "https://images.cnblogs.com/cnblogs_com/blogs/766345/galleries/2274688/o_230215035425_canvas.png"; image.onload = function () { // 坐标(10,10)处,宽高 200*200 的图像,从坐标(20,20)处裁剪出宽高 50*50 的图像按照宽高 200*200显示。 ctx.drawImage(image, 20, 20, 50, 50, 10, 10, 200, 200) }
- 平铺图像
var image = new Image(); image.src = "https://images.cnblogs.com/cnblogs_com/blogs/766345/galleries/2274688/o_230215035425_canvas.png"; image.onload = function () { var pattern = ctx.createPattern(image, 'repeat'); // createPattern设置平铺模式,可选值有:repeat(默认), repeat-x, repeat-y, no-repeat ctx.fillStyle = pattern; ctx.fillRect(5,5,395,395); }
- 反转像素
ctx.fillStyle = '#f00'; ctx.fillRect(10,10,100,100); var imageData = ctx.getImageData(10,10,50,50); // 从坐标(10,10)处,获取图像信息对象,宽高为50*50 for(var i=0;i<imageData.data.length;i+=4) { // imageData.data: ArrayBuffer包含了图像像素信息,以RGBA的顺序存放,范围0-255 imageData.data[i] = 255 - imageData.data[i]; imageData.data[i + 1] = 255 - imageData.data[i + 1]; imageData.data[i + 2] = 255 - imageData.data[i + 2]; imageData.data[i + 3] = 255; } ctx.putImageData(imageData,35,35); // 按照处理的图像信息(反转像素后的50*50图像),在坐标(35,35)处生成图像
注意:反转像素使用的是填充矩形,使用 image 可以绘制图像,但获取像素信息会导致跨域报错:Uncaught DOMException: Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted by cross-origin data.
如下代码测试报错
var image = new Image(); image.src = "https://images.cnblogs.com/cnblogs_com/blogs/766345/galleries/2274688/o_230215035425_canvas.png"; image.onload = function () { ctx.drawImage(image,10,10); var imageData = ctx.getImageData(10,10,image.width,image.height) console.log(imageData) }
-
绘制文本
- 填充文本
// font为综合属性,依次对应值:font-style font-variant font-weight font-size/line-height font-family ctx.font="normal normal 400 30px/1.5 Microsoft YaHei"; ctx.fillStyle = 'skyblue'; ctx.fillText('Hello Canvas!', 50,50); // 坐标(50,50)处,绘制填充文本 Hello Canvas!
- 描边文本
ctx.font="normal normal 400 30px/1.5 Microsoft YaHei"; ctx.strokeStyle = 'skyblue'; // 可以设置渐变,生成渐变文本 ctx.strokeText('Hello Canvas!', 50,100);
-
绘制动画
- canvas 动画相关API
ctx.ratate(弧度); // 绘图旋转,轴为原点旋转,旋转具有累加效果; ctx.translate(x,y); // 绘图移动,原点由(0,0)移动到(x,y); ctx.scale(x, y); // 绘图缩放,x,y表示缩放比例,>1表示放大,<1表示缩小; ctx.clearRect(0,0,c1.width,c1,height); // 从原点处,宽高为画布宽高,清除图像
注意:clearRect() 是 canvas 绘制动画的关键 api,canvas 绘制动画的本质是一遍遍擦除重绘,如 canvas 时钟案例。
Svg
Svg 是基于 XML 绘制的矢量图,Svg 图像是可以通过 DOM 元素获取的,并且可以通过 DOM 方法设置图像属性。
Svg 绘图类似于 Canvas 本质是一个 300*150 的 inline-block,也称之为画布。绘制图像是通过一系列 svg 标签,每个 svg 标签可以获取其 DOM 对象,并执行 DOM 操作。
基本用法
<svg id="s1" width="400" height="400">
<!-- svg 绘图标签 -->
</svg>
绘图标签
-
绘制线条
- 绘制直线
<line x1="10" y1="10" x2="200" y2="200" style="stroke: blue; stroke-width: 3;" />
注意:svg 与 canvas 一样具有坐标系概念,并且坐标系一致。
- 绘制折线
<polyline points="20,30 50,70 100,60 150,120" style="fill: none; stroke: #f00; stroke-width: 3;" />
- 绘制曲线
<path d="M 10 110 C 20 140, 40 140, 50 110" stroke="black" fill="transparent"/>
注意: path路径标签有很强大的功能,不单单是绘制曲线,根据d的value值命令不同,可以绘制更多图像。详细可以查看 path MDN
-
绘制简单形状
- 绘制矩形
<rect x="10" y="10" width="30" height="30" stroke="black" fill="transparent" stroke-width="2"/>
- 绘制多边形
<polygon points="50,160 55,180 70,180 60,190 65,205 50,195 35,205 40,190 30,180 45,180" stroke="green" fill="transparent" stroke-width="5"/>
- 绘制圆
<circle cx="25" cy="75" r="20" stroke="red" fill="transparent" stroke-width="5"/>
- 绘制椭圆
<ellipse cx="75" cy="75" rx="20" ry="5" stroke="red" fill="transparent" stroke-width="5"/>
-
绘制渐变
- 绘制线性渐变
<defs> <linearGradient id="linear" x1="0" x2="0" y1="0" y2="1"> <stop offset="0%" stop-color="red"/> <stop offset="50%" stop-color="black" stop-opacity="0"/> <stop offset="100%" stop-color="blue"/> </linearGradient> </defs> <rect x="10" y="120" rx="15" ry="15" width="100" height="100" fill="url(#linear)"/>
- 绘制径向渐变
<defs> <radialGradient id="radial" cx="0.25" cy="0.25" r="0.5"> <stop offset="0%" stop-color="red"/> <stop offset="100%" stop-color="blue"/> </radialGradient> </defs> <rect x="10" y="120" rx="15" ry="15" width="100" height="100" fill="url(#radial)"/>
-
绘制文本
- 绘制填充文本
<text x="30" y="80" fill="skyblue" style="font-size: 30px;">Hello Svg!</text>
- 绘制描边文本
<text x="30" y="40" fill="none" stroke="blue" stroke-width="1" style="font-size: 30px;">Hello Svg!</text>
-
绘制图像
<image xlink:href="https://images.cnblogs.com/cnblogs_com/blogs/766345/galleries/2274688/o_230215035425_canvas.png" x="10" y="10" height="150px" width="200px"/>
-
绘制变换
<rect x="20" y="20" width="20" height="20" transform="translate(30,40)" /> <rect x="50" y="20" width="20" height="20" transform="rotate(45)" /> <rect x="90" y="20" width="20" height="20" transform="scale(0.5, 1)" />
地理定位
HTML5 地理定位功能依托于浏览器 window.navigator.geolocation 属性,通过判断该属性是否存在可以检测浏览器是否支持地理定位功能。该属性包含三个地理定位 api:getCurrentPosition(), watchPosition(), clearPosition()
点击查看代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>地理位置</title>
</head>
<body>
<div>Geolocation</div>
<script type="text/javascript">
if(window.navigator.geolocation) {
console.log(window.navigator.geolocation)
} else {
alert('您的浏览器不支持地理定位功能!')
}
</script>
</body>
</html>
getCurrentPosition
用于获取用户当前的地理位置信息,该方法有三个参数,success回调,error回调,options参数(可缺省)。
window.navigator.geolocation.getCurrentPosition(
position => {
console.log(position.timestamp, position.coords)
// position.coords.latitude 纬度
// position.coords.longtitude 经度
// position.coords.altitude 海拔
// position.coords.accuracy 经纬度的精度(米)
// position.coords.altitudeAccuracy 海拔的进度(米)
// position.coords.heading 前进方向,用面朝正北方向顺时针旋转角度表示
// position.coords.speed 前进速度
},
error => {
if(error.code === 1) {
alert('用户拒绝位置服务')
} else if(error.code === 2) {
alert('获取不到位置信息')
} else if(error.code === 3) {
alert('获取位置信息超时')
} else {
console.log(error)
alert('发生位置错误')
}
},
{
enableHighAccuracy: true, // 是否要求高精度的位置信息
timeout: 100 * 1000,
maximumAge: 30 * 1000, // 最大缓存时间
}
)
watchPosition
用于持续监听用户当前的地理位置信息,地理位置发生变化自动调用该函数,参数与 getCurrentPosition 一致。
var watchId = window.navigator.geolocation.watchPosition(
position => {
console.log(position.timestamp, position.coords)
// position.coords.latitude 纬度
// position.coords.longtitude 经度
// position.coords.altitude 海拔
// position.coords.accuracy 经纬度的精度(米)
// position.coords.altitudeAccuracy 海拔的进度(米)
// position.coords.heading 前进方向,用面朝正北方向顺时针旋转角度表示
// position.coords.speed 前进速度
},
error => {
if(error.code === 1) {
alert('用户拒绝位置服务')
} else if(error.code === 2) {
alert('获取不到位置信息')
} else if(error.code === 3) {
alert('获取位置信息超时')
} else {
console.log(error)
alert('发生位置错误')
}
},
{
enableHighAccuracy: true,
timeout: 3 * 1000,
maximumAge: 30 * 1000,
}
)
注意:watchPosition 会返回一个句柄,本质是一个数字,类似 setInterval 返回一致,该句柄用于停止监听。
clearPosition
用于停止 watchPosition 的监听,该方法有一个参数:watchPosition() 的返回值。
var watchId = window.navigator.geolocation.watchPosition(
position => {
console.log(position.timestamp, position.coords)
// position.coords.latitude 纬度
// position.coords.longtitude 经度
// position.coords.altitude 海拔
// position.coords.accuracy 经纬度的精度(米)
// position.coords.altitudeAccuracy 海拔的进度(米)
// position.coords.heading 前进方向,用面朝正北方向顺时针旋转角度表示
// position.coords.speed 前进速度
},
error => {
if(error.code === 1) {
alert('用户拒绝位置服务')
} else if(error.code === 2) {
alert('获取不到位置信息')
} else if(error.code === 3) {
alert('获取位置信息超时')
} else {
console.log(error)
alert('发生位置错误')
}
},
{
enableHighAccuracy: true,
timeout: 3 * 1000,
maximumAge: 30 * 1000,
}
)
window.navigator.geolocation.clearPosition(watchId)
注意:以上方法可以获取用户的地理位置信息,但是我们获取都是经纬度和海拔信息,无法转换成常规的地址信息。因此,需要借助地图 API 做逆地址解析,如 百度地图 BMap,高德地图 AMap
Web Worker
Web Worker是多线程工作,运行在后台的JavaScript,无法请求或访问页面,不会影响页面性能。
基本用法
-
主进程中创建 worker 对象
var worker = new Worker('./worker.js')
-
数据传递
- 主线程传递数据
worker.postMessage(params); // postMessage只接受一个参数
- worker 线程传递数据
self.postMessage(params); // self 可省略,即 postMessage();
-
接收数据
- 主线程接收数据
worker.onmessage = function(event) { event.data // worker 传递的参数 }
- worker 线程接收数据
self.onmessage = function(event) { event.data // 主线程传递的参数 }
-
关闭 worker 线程
- 主线程关闭 worker 线程
worder.terminate();
- worker 线程内部关闭
self.close();
注意:web worker 需要加载 worker.js 文件,而浏览器因同源策略无法加载本地文件,需要借助服务器将 worker.js 资源静态化,可参照 web worker demo。
Web Storage
sessioStorage
sessioStorage 将数据保存在 session 对象中,而 session 对象是浏览器打开窗口的过程中,为用户浏览网站提供的内存对象(session 对象与窗口绑定),一旦浏览器关闭,内存会被清空。因此,sessioStorage 是临时存放数据,随浏览器关闭而销毁。
- 存
sessioStorage.setItem(key,value); // key, value 必须为字符串
- 取
sessioStorage.getItem(key);
- 删
sessioStorage.removeItem(key;
- 清空
sessioStorage.clear();
注意:浏览器同源策略对 sessioStorage 的影响:
不同源的情况下,A,B 页面是断然无法共享 sessioStorage 的。
同源的情况下,B 页面由 A 页面中链接导航打开,则 B 页面 session 对象是 A 页面 session 对象的复制,且为值引用,相互对立,不受干扰。
同源的情况下,A,B 页面是不同窗口分别打开的,则 A,B 页面的 session 对象无关联。
localStorage
localStorage 将数据保存在客户端本地,通常保存在磁盘或其他存储介质中,浏览器关闭不会影响磁盘和存储介质(存储与”源“绑定)。因此,localStorage 是永久存储(不主动清理和损毁磁盘的情况下)。
- 存
localStorage.setItem(key,value); // key, value 必须为字符串,引用类型数据可以通过JSON方式进行存储,JSON API: JSON.stringify(), JSON.parse()
- 取
localStorage.getItem(key);
- 删
localStorage.removeItem(key;
- 清空
localStorage.clear();
注意:浏览器同源策略对 localStorage 的影响:
不同源的情况下,A,B 页面是断然无法共享 localStorage 的。
同源的情况下,A,B 页面共享 localStorage,共用同一存储,相互干扰,相互影响,可以监听 storage 事件来观测 local 数据变化。
Web SQL
Web SQl 是客户端数据库,同服务器端 SQL Serve 和 Oracle 一致,可以使用 SQL 语句进行一些数据库操作,如表和数据的增删改查等;Web SQL的三个核心 API:
openDatabase
用于打开或创建数据库对象的方法,指定数据名,存在即打开,不存在则创建;
var db = openDatabase('testDB', '1.0', 'this is a db for test', 5 * 1024 * 1024) // 参数分别为:数据库名称,版本,描述,大小
if(!db) {
alert('创建/打开 数据库失败')
} else {
// 执行数据库操作(transacion, executeSql)
alert('创建/打开 数据库成功')
}
transacion
用于创建并控制事务,可进行事务提交和回滚。事务:一系列数据操作的集合,所有操作完成,事务提交,否则,事务回滚,取消所有操作。
- 创建表操作
const createTabelSQL = "create table if not exists User (id UNIQUE, name TEXT)"
const createData = []
db.transaction(res => {
res.executeSql(
createTabelSQL,
createData,
success => {
alert('创建 User 表成功')
},
error => {
alert('创建 User 表失败,原因:', error.message)
}
)
})
- 删除表操作
const dropSQL = "drop table User"
const dropData = []
db.transaction(res => {
res.executeSql(
dropSQL,
dropData,
success => {
alert('表 User 删除成功')
},
error => {
alert('表 User 删除失败,原因:', error.message)
}
)
})
注意:transacion 参数为回调函数,回调函数内部执行 executeSql。
executeSql
用于执行 SQL 操作,参数有四个,分别为:sql,data,success回调, error回调。
- 插入数据
const insertSQL = "insert into User(id, name) values(?, ?)"
const insertData = [1, '张三']
db.transaction(res => {
res.executeSql(
insertSQL,
insertData,
success => {
alert('数据插入成功')
},
error => {
alert('数据插入失败,原因:', error.message)
}
)
})
- 更新数据
const updateSQL = "update User set name=? where id=?"
const updateData = ["李四", 1]
db.transaction(res => {
res.executeSql(
updateSQL,
updateData,
success => {
alert('更新 User 表成功')
},
error => {
alert('更新 User 表失败,原因:', error.message)
}
)
})
- 查询数据
const selectSQL = "select * from User"
const selectData = []
db.transaction(res => {
res.executeSql(
selectSQL,
selectData,
(success, data) => {
console.log(data.rows)
},
error => {
alert('数据查询失败,原因:', error.message)
}
)
})
- 删除数据
const deleteSQL = "delete from User"
const deleteData = []
db.transaction(res => {
res.executeSql(
deleteSQL,
deleteData,
success => {
alert('数据删除成功')
},
error => {
alert('数据删除失败,原因:', error.message)
}
)
})
注意:executeSql 第二个参数是必须的,为空可以设置为空数组。此外,SQL 语句中可以使用 ? 占位符,按照顺序对应 data 中的数据项。
Web Socket
Web Socket 是全双工通信,应用 Web Socket 技术可以做到:web 端在任意时刻请求服务端,服务端在任意时刻推送 web 端;与 http 相比,Web Socket 解决了服务端无法主动向 web 端推送的功能,更是有效解决了消息时效性问题,目前多应用于响应系统。
基于 nodejs 的使用
- web 端:
let ws = new WebSocket('ws://127.0.0.1:3000/public')
ws.onopen = () => {
ws.send('hello server')
};
ws.onmessage = ev => {
console.log(ev.data)
}
- 服务端:
const express = require('express')
const path = require('path')
const http = require('http')
const Ws = require('ws').Server
const app = express()
app.use('/public',express.static(path.resolve(__dirname, './public/')))
const server = http.createServer(app)
server.listen(3000)
let wsServer = new Ws({ server })
wsServer.on('connection', socket => {
socket.on('message', msg => {
console.log('客户端发送过来的消息:' + msg);
socket.send('服务器说:你好客户端')
})
});
注意:上例是使用 ws 模块进行的简单使用,项目地址:web socket demo,市场上有多种 web socket库,调用方式也不同,如 socket.io 库。
拖放 API
拖放 API 是指:drag 和 drop 行为过程触发的 7 个事件,以及拖放的两个对象:源对象(拖的对象),目标对象(放的对象)。
在 HTML5 当中,任何元素均可以被拖放,但是实施拖放必须指定元素属性 draggable = true
。
点击查看代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>拖放 API</title>
<style type="text/css">
#origin {
width: 100px;
height: 100px;
background-color: skyblue;
float: left;
}
#desination {
width: 200px;
height: 200px;
background-color: orchid;
float: right;
margin-right: 100px;
}
</style>
</head>
<body>
<div id="origin" draggable="true"></div>
<div id="desination"></div>
<script type="text/javascript">
const origin = document.getElementById('origin')
origin.addEventListener('dragstart',function(event) {
console.log('拖 开始')
console.log(event)
})
origin.addEventListener('drag', function(event) {
console.log('拖 进行')
})
origin.addEventListener('dragend', function(event) {
console.log('拖 结束')
})
const desination = document.getElementById('desination')
desination.ondragenter = function(event) {
console.log('拖 进入')
}
desination.ondragover = function(event) {
console.log('拖 悬停')
// event.preventDefault()
}
desination.ondragleave = function(event) {
console.log('拖 离开')
}
desination.ondrop = function(event) {
console.log('放')
}
</script>
</body>
</html>
源对象和目标对象
发生拖放行为,则存在两个相对物体,即 A 物体 放置 B 物体上,我们称之 A 物体为源对象,B 物体为目标对象。
- 源对象(origin)
-
origin.ondragstart
拖动开始触发的事件,拖放过程执行 1 次。 -
origin.ondrag
拖动过程中触发的事件,拖放过程执行 多 次。 -
origin.ondragend
拖动结束触发的事件,拖放过程执行 1 次。
- 目标对象
-
desination.ondragenter
源对象进入目标对象区域触发的事件,拖放过程执行 1 次。 -
desination.ondragover
源对象悬停目标对象上方触发的事件,拖放过程执行 n 次。 -
desination.ondragleave
源对象离开目标对象区域触发的事件,拖放过程执行 0 或 1 次。 -
desination.ondrop
源对象在目标对象上方释放时触发的事件,拖放过程执行 0 或 1 次。
注意:dragover 默认行为是悬停上方,释放后立即执行 dragleave,而释放后执行 drop 需要阻止 dragover 默认行为,因此执行 dragleave 或 drop 是需要根据 dragover 是否阻止默认行为来决定的。
dataTransfer
拖放事件对象中存在一个 dataTransfer 对象,可以通过这个对象进行拖放过程中的交互。
源对象和目标对象可以借助 dataTransfer 对象的 setData() 和 gerData() 方法进行数据传递;
const origin = document.getElementById('origin')
origin.addEventListener('dragstart',function(event) {
console.log('拖 开始')
event.dataTransfer.setData('name', 'blue block')
})
const desination = document.getElementById('desination')
desination.ondragover = function(event) {
event.preventDefault()
}
desination.ondrop = function(event) {
console.log('放')
const name = event.dataTransfer.getData('name')
console.log(name)
}
注意:dataTransfer 对象的 setDragImage() 方法可以自定义拖放图标,该方法有三个参数:image,图标与 x 轴偏移量,图标与 y 轴偏移量。
后记
HTML5 新特性暂时更新致此吧,还有其他特性会以碎片化学习前端系列更新。博客中新特性均是基本使用,没有涉及工作中的应用场景,我的考虑是先广而全,后精而深,慢慢会结合场景更新。
本文来自博客园,作者:深巷酒,转载请注明原文链接:https://www.cnblogs.com/huangminghua/p/17104375.html