HMTL5
HTML5新特性 Unit01
保留首页的状态音频、视频
HTML5提供的音视频标签可以实现在网页内部嵌入音视频播放功能。
音频标签
浏览器支持的音频格式:mp3, wav, ogg
简写方式:
<audio src="音频文件路径.mp3" controls></audio>
标准方式:
<audio controls>
<source src="音频文件路径.mp3" type="audio/mpeg" />
<source src="音频文件路径.wav" type="audio/wav" />
<source src="音频文件路径.ogg" type="audio/ogg" />
什么破浏览器,换一个吧,chrome挺好的。
</audio>
常用属性
<audio src="音频文件路径.mp3"
controls 是否显示控制面板
autoplay 是否资源加载完毕后自动播放
muted 是否默认静音
loop 是否单曲循环
preload="" 音频的预加载模式
></audio>
preload的可选值:
none不进行任何音频的预加载
auto尽可能的加载音频资源
metadata只加载音频的元数据(音频时长、格式、视频分辨率...)
视频标签
视频标签支持:mp4, webm, ogg
简写方式:
<video src="视频文件路径.mp4" controls></video>
常用属性
<video src="音频文件路径.mp3"
controls 是否显示控制面板
autoplay 是否资源加载完毕后自动播放
muted 是否默认静音
loop 是否单曲循环
preload="" 音频的预加载模式
width="" 播放器的宽度 (与视频内容无关)
height="" 播放器的高度
poster="" 视频的海报帧路径 (未播放时的封面图片)
></video>
audio、video标签的dom操作
<audio id="a" src="xxxx.mp3" controls></audio>
<script>
let a = document.getElementById('a')
a.src = 'tyyyy.mp3' // 对属性进行操作
a.play() // 调用a的方法 播放
</script>
与媒体相关的DOM接口包含:
HTMLMediaElement是以下两个接口的父接口
HTMLAudioElement描述<audio>
HTMLVideoElement描述<video>
百度搜索: HTMLMediaElement MDN
HTMLMediaElement提供的DOM接口
https://www.w3school.com.cn/tags/html_ref_audio_video_dom.asp
HTML5 Audio/Video 属性
let a = document.getElementById('a')
a.autoplay = true
属性 描述 autoplay 设置或返回是否在加载完成后随即播放音频/视频 controls 设置或返回音频/视频是否显示控件(比如播放/暂停等) currentTime 设置或返回音频/视频中的当前播放位置(以秒计) defaultMuted 设置或返回音频/视频默认是否静音 defaultPlaybackRate 设置或返回音频/视频的默认播放速度 duration 返回当前音频/视频的长度(以秒计) ended 返回音频/视频的播放是否已结束 loop 设置或返回音频/视频是否应在结束时重新播放 muted 设置或返回音频/视频是否静音 networkState 返回音频/视频的当前网络状态 paused 设置或返回音频/视频是否暂停 playbackRate 设置或返回音频/视频播放的速度 src 设置或返回音频/视频元素的当前来源 volume 设置或返回音频/视频的音量
HTML5 Audio/Video 方法
let a = document.getElementById('a')
a.play()
a.pause()
方法 描述 play() 开始播放音频/视频 pause() 暂停当前播放的音频/视频
HTML5 Audio/Video 事件
let a = document.getElementById('a')
a.addEventListener("error", ()=>{ error时执行回调 })
HTML5新特性 Unit02
audio、video标签的dom操作
<audio id="a" src="xxxx.mp3" controls></audio>
<script>
let a = document.getElementById('a')
a.src = 'tyyyy.mp3' // 对属性进行操作
a.play() // 调用a的方法 播放
</script>
与媒体相关的DOM接口包含:
HTMLMediaElement是以下两个接口的父接口
HTMLAudioElement描述<audio>
HTMLVideoElement描述<video>
百度搜索: HTMLMediaElement MDN
HTMLMediaElement提供的DOM接口
https://www.w3school.com.cn/tags/html_ref_audio_video_dom.asp
HTML5 Audio/Video 属性
let a = document.getElementById('a')
a.autoplay = true
属性 描述 autoplay 设置或返回是否在加载完成后随即播放音频/视频 controls 设置或返回音频/视频是否显示控件(比如播放/暂停等) currentTime 设置或返回音频/视频中的当前播放位置(以秒计) defaultMuted 设置或返回音频/视频默认是否静音 defaultPlaybackRate 设置或返回音频/视频的默认播放速度 duration 返回当前音频/视频的长度(以秒计) ended 返回音频/视频的播放是否已结束 loop 设置或返回音频/视频是否应在结束时重新播放 muted 设置或返回音频/视频是否静音 networkState 返回音频/视频的当前网络状态 paused 设置或返回音频/视频是否暂停 playbackRate 设置或返回音频/视频播放的速度 src 设置或返回音频/视频元素的当前来源 volume 设置或返回音频/视频的音量
HTML5 Audio/Video 方法
let a = document.getElementById('a')
a.play()
a.pause()
方法 描述 play() 开始播放音频/视频 pause() 暂停当前播放的音频/视频
HTML5 Audio/Video 事件
let a = document.getElementById('a')
a.addEventListener("error", ()=>{ error时执行回调 })
事件 描述 canplay 当浏览器可以播放音频/视频时 durationchange 当音频/视频的时长已更改时 error 当在音频/视频加载期间发生错误时 loadedmetadata 当浏览器已加载音频/视频的元数据时 pause 当音频/视频已暂停时 play 当音频/视频已开始或不再暂停时 ratechange 当音频/视频的播放速度已更改时 timeupdate 当目前的播放位置已更改时 volumechange 当音量已更改时 waiting 当视频由于需要缓冲下一帧而停止
下载该app的android安装包。 xxxxx.apk。扒app的图片资源:
-
将
apk修改后缀名为zip:xxxxx.zip。直接解压。 -
图片就在解压之后的文件夹里。
扒服务端数据:
专业一些应该用爬虫技术。
Canvas
什么是canvas?
canvas(画布)是可以用Javascript来绘制图形的html元素,其语法结构:
<canvas width="画布分辨率的宽度" height="画布分辨率的高度">
</canvas>
canvas的应用
网页特效。
网页游戏。
数据可视化图表。
canvas的使用
基本使用步骤:
<canvas id="canvas"
width="画布分辨率的宽度" height="画布分辨率的高度">
</canvas>
let cvs = document.getElementById('canvas')
let ctx = cvs.getContext('2d')
ctx.fillStyle = 'red'
ctx.fillRect()
getContext方法需要提供一个上下文类型参数:
2d: 将会返回CanvasRenderingContext2D对象,绘制二维图形。
webgl: 将会返回WebGLRenderingContext对象,绘制三维图形。
CanvasRenderingContext2D对象的常用接口
填充操作:
ctx.fillStyle = "red"
ctx.fillRect(x, y, width, height) // 左上角坐标,宽,高
描边操作:
ctx.strokeStyle = "blue"
ctx.strokeRect(x,y,width, height) // 左上角坐标,宽,高
绘制文本:
ctx.font = '25px 微软雅黑'
ctx.strokeText(text, x, y) // 文本内容,输出文本的位置(x,y)
ctx.fillText(text, x, y)
Canvas的路径
路径的本质就是将预先设定好的坐标点按照顺序连接起来所形成的图形。
路径的绘制步骤:
调用
ctx.beginPath()开始一条新路径。调用
ctx.moveTo(x,y)将画笔移动到某一个位置。调用相关方法开始绘制路径(例如:
ctx.lineTo(x, y))最后通过调用
ctx.stroke()或ctx.fill()对路径进行描边或填充。
案例:绘制一个三角形。
HTML5新特性 Unit03
Canvas的路径
路径的本质就是将预先设定好的坐标点按照顺序连接起来所形成的图形。
路径的绘制步骤:
调用
ctx.beginPath()开始一条新路径。调用
ctx.moveTo(x,y)将画笔移动到某一个位置。调用相关方法开始绘制路径(例如:
ctx.lineTo(x, y))最后通过调用
ctx.stroke()或ctx.fill()对路径进行描边或填充。
案例:绘制一个三角形。
案例:你画我猜的画板。
移动端设备的
touch相关事件:
touchstart开始触摸
touchend结束触摸
touchmove触摸并移动
touchcancel取消触摸
实现步骤
-
当
touchstart时,开启新路径。moveTo到当前触摸位置。 -
当
touchmove时,lineTo到目标位置,并且描边即可。
HTML5提供了一些绘制路径的简单方法:
ctx.rect() 用于绘制矩形路径
ctx.rect(x, y, width, height)
ctx.arc() 用于绘制圆弧路径
// (x,y)圆心坐标, radius半径,起始弧度值,结束弧度值
ctx.arc(x, y, radius, startangle, endangle)
Canvas动画
动画的实现原理即每隔一段时间(非常快,1/60秒)重绘canvas。 每次绘制时,内容都会有些许变化,由于视觉残留现象,出现动画效果。
window.setInterval(()=>{
计算最新的元素属性,绘制UI
}, 1000/60)
案例:实现视频弹幕。
-
在
video标签之上蒙一层canvas。 -
添加
input与button,实现弹幕的发送功能。-
在全局准备一个
dmlist数组用于存放所有的弹幕对象。 -
当点击发送按钮时,构造一个全新的
dm对象,添加到dmlist中。{x:600, y:随机, dmtext:弹幕内容} -
在全局启动一个周期定时器,每
1000/60秒遍历dmlist,将弹幕对象绘制在界面中。(需要更新每个弹幕的x坐标,实现动画)
-
动画卡顿的本质:掉帧
原本每秒应该绘制60次,但是由于某些原因导致无法达到刷新率,掉的几帧图像就会有卡顿的感觉。
推荐使用HTML5提供的window.requestAnimationFrame()方法来解决动画卡顿问题。
window.requestAnimationFrame(callback)方法的作用是:请求浏览器下次绘制界面时执行callback方法。可以将更新UI的方法写在callback中。
基于requestAnimationFrame()方法实现动画绘制的代码的基本结构:
function draw(){
重新计算绘制UI
window.requestAnimationFrame(draw)
}
draw()
地理定位
定义基础与原理
IP定位运营商基站定位
GPS卫星定位
地理位置的获取
地理定位API允许用户向web应用程序提供他们的位置,但是这个操作需要用户授权。
获取地理位置的代码如下:
let geoloc = window.navigator.geolocation
// 异步获取经纬度,通过回调方法返回结果
let success = (msg)=>{}
let err = (e)=>{}
let option = {timout: 5000}
geoloc.getCurrentPosition(success, err, option)
一旦定位获取成功, 将会回调success方法,将位置对象作为参数传给回调方法:
GeolocationPosition对象
coords: GeolocationCoordinates
accuracy: 150 经纬精准度
altitude: null 海拔高度
altitudeAccuracy: null 海拔精度
heading: null
latitude: 31.230416 纬度
longitude: 121.473701 经度
speed: null 速度
timestamp: 1638952169685
接入第三方位置服务平台 - 百度地图、高德地图、腾讯地图
一旦接入了这些第三方位置服务平台,就可以方便的在自己的网页中嵌入地图控件。还可以对地图进行各种操作:在地图中添加标记、访问第三方web服务,实现公交线路查询、驾车线路查询、周边检索、地址解析等功能。
接入高德地图开放平台
https://lbs.amap.com/
申请秘钥与jscode
显示地图
1.准备一个html页面,提供一个div,作为地图的容器。设置css样式。
<div id="container" style="xxxxx"></div>
2.引入显示高德地图所需要的资源:
<script type="text/javascript">
window._AMapSecurityConfig = {
securityJsCode:'您申请的安全密钥jscode',
}
</script>
<script type="text/javascript" src="https://webapi.amap.com/maps?v=1.4.15&key=您申请的key值"></script>
3.创建AMap对象,在div中显示地图:
var map = new AMap.Map('container', {
zoom:11,//级别
center: [116.397428, 39.90923],//中心点坐标
viewMode:'3D'//使用3D视图
});
HTML5新特性 Unit04
显示地图
-
1.准备一个html页面,提供一个div,作为地图的容器。设置css样式。 <div id="container" style="xxxxx"></div> 2.引入显示高德地图所需要的资源: <script type="text/javascript"> window._AMapSecurityConfig = { securityJsCode:'您申请的安全密钥jscode', } </script> <script type="text/javascript" src="https://webapi.amap.com/maps?v=1.4.15&key=您申请的key值"></script> 3.创建AMap对象,在div中显示地图: var map = new AMap.Map('container', { zoom:11,//级别 center: [116.397428, 39.90923],//中心点坐标 viewMode:'3D'//使用3D视图 });
在地图中添加点标记,并且绑定事件弹出信息窗口
// 将当前位置作为一个点标记 添加到地图上
let marker = new AMap.Marker({
position: new AMap.LngLat(lng, lat),
title: '我的家'
})
// 为marker绑定事件
marker.on('click', (e)=>{
console.log(e)
let infoWindow = new AMap.InfoWindow({ //创建信息窗体
isCustom: true, //使用自定义窗体
content:'<div style="padding:10px; background:#fff;">我的家就在这</div>', //信息窗体的内容可以是任意html片段
offset: new AMap.Pixel(16, -45)
});
// 在 [map地图对象] 上的 [标记点位置] 显示窗口
infoWindow.open(map, e.target.getPosition())
})
map.add(marker)
通过这段代码可以发现高德地图API设计完全符合面向对象思想。那么阅读文档时需要认识每一个类拥有的属性、方法、功能。使用时基本符合:创建对象、调用对象方法、访问对象属性等合理操作。
在地图中添加控件
// 添加高德地图内置的控件
// 同时引入工具条插件,比例尺插件和鹰眼插件
AMap.plugin([
'AMap.ToolBar',
'AMap.Scale',
'AMap.OverView',
'AMap.MapType',
'AMap.Geolocation'
], function(){
// 在图面添加工具条控件,工具条控件集成了缩放、平移、定位等功能按钮在内的组合控件
map.addControl(new AMap.ToolBar());
// 在图面添加比例尺控件,展示地图在当前层级和纬度下的比例尺
map.addControl(new AMap.Scale({
offset: new AMap.Pixel(60, 30)
}));
// 在图面添加鹰眼控件,在地图右下角显示地图的缩略图
map.addControl(new AMap.OverView({isOpen:true}));
// 在图面添加类别切换控件,实现默认图层与卫星图、实施交通图层之间切换的控制
map.addControl(new AMap.MapType());
// 在图面添加定位控件,用来获取和展示用户主机所在的经纬度位置
map.addControl(new AMap.Geolocation());
});
高德地图提供了很多插件plugin。在使用时需要先AMap.plugin引入插件,才可以创建对象,使用这些插件。通过对每个对象的属性进行操作,就可以改变该插件在页面中的显示效果。
访问高德地图提供的web服务
// 添加高德地图内置的控件
// 同时引入工具条插件,比例尺插件和鹰眼插件
AMap.plugin([
'AMap.PlaceSearch',
'AMap.Geocoder'
], function(){
// 逆地理编码
let coder = new AMap.Geocoder({extensions:'all'})
coder.getAddress([lng, lat], (status, result)=>{
console.log(status, result)
})
// 搜索地点
let placeSearch = new AMap.PlaceSearch({
city:'北京'
})
placeSearch.search('医院', function(status, result){
console.log(status, result)
})
});
由此可知,高德提供了很多web服务,通过访问这些服务,可以获取相应的结果。在使用的使用依然需要先引入插件对象,才可以创建对象,调用对象方法来访问这些web服务接口。
拖放
拖放是将对象从一个位置拖拽带另一个位置的操作,任何HTML元素都可以进行拖放操作。但是为了保持兼容性, 建议在拖放的对象上添加属性:
<p draggable="true">xx</p>
DragEvent拖拽相关事件
DragEvent指拖拽相关事件,其继承自MouseEvent和Event接口。
拖拽事件涉及到的事件源有两类:源对象(p元素)、目标对象(div元素)。那么拖拽过程中针对源对象与目标对象都会有一些拖拽相关事件的产生。
源对象事件
dragstart 开始拖拽源对象时触发该事件
drag 源对象拖拽过程中将会触发该事件(持续触发)
dragend 拖拽完毕后(释放鼠标)触发该事件
目标对象事件
dragenter 当拖拽着源对象进入目标对象时,触发目标对象上绑定的该事件
dragover 当拖拽着源对象在目标对象中悬停时,触发该事件
dragleave 当拖拽着源对象离开目标对象时,触发目标对象上绑定的该事件
drop 当拖拽着源对象在目标对象上释放时,触发目标对象上绑定的该事件
注意:
在
dragover事件处理函数中需要加入:event.preventDefault()阻止浏览器默认事件的处理,否则不会触发目标对象的drop事件。
firefox或360浏览器对于拖拽的元素有默认事件处理(打开新页面加载资源)。所以也需要阻止这个行为,需要在drop事件中添加:event.stopPropagation()
event.preventDefault()
拖拽过程中的数据传输
需求:拖拽p标签进入div,释放后,将p元素追加到div子元素的末尾。
拖拽span标签进入div,释放后,将span追加到div子元素的末尾。
...等...
若上需求,需要在开始拖拽(dragstart)时,将源对象的信息(tagname/innerHTML)存起来,在触发drop时,将存储的信息读取出来,重新构造新的dom对象,追加到div中即可。
HTML5在单个的拖拽过程中提供了一种数据传输方案,需要借助DataTransfer对象就可以进行数据的存储于读取:
p.ondragstart= (event)=>{
let df = event.dataTransfer
df.setData('tagname', 'p')
df.setData('innerHTML', p.innerHTML)
}
div.ondrop = (event)=>{
let df = event.dataTransfer
df.getData('tagname') // -> 'p'
df.getData('innerHTML') // -> '文本'
}
实现拖拽上传文件
文件上传流程与协议规范
文件上传流程
客户端选择需要上传的文件,点击上传,开始建立连接,准备上传。
服务端接收连接请求,完成连接的建立,接收上传的文件(遵守
http协议)。服务端把接收到的文件数据,存入服务器的文件系统(
/h/x.jpg)保存完毕后即上传成功。之后浏览器可以通过链接地址访问该资源。
协议规范
要求客户端提交文件的请求方式必须是
POST。发请求时必须携带消息头(
Header):Content-Type:multipart/form-data客户端本地文件在请求
body部分以数据流的方式传输给服务端。服务端接收客户端传来的数据流,便接收边保存到服务器的磁盘中。
如何获取拖拽文件的基本信息
当用户吧文件拖拽到div中触发drop后,浏览器将会拉取选中文件的基本信息,通过dataTransfer对象保存并传输文件信息。所以可以通过以下代码获取拖拽的文件数据:
div.ondrop = (event)=>{
let files = event.dataTransfer.files
// 开始上传
}
客户端发送上传文件请求
拖拽上传需要使用ajax的方式整理上传的参数,实现文件上传。
基于axios发送ajax请求,上传文件的基本写法如下:
// FormData对象用于封装表单参数数据
// 存储所有需要传给服务端的key=value键值对数据
let fd = new FormData()
fd.append('name', '张三')
fd.append('uploadFile', file对象)
axios.post('/upload', fd)
HTML5新特性 Unit05
客户端发送上传文件请求
拖拽上传需要使用ajax的方式整理上传的参数,实现文件上传。
基于axios发送ajax请求,上传文件的基本写法如下:
// FormData对象用于封装表单参数数据
// 存储所有需要传给服务端的key=value键值对数据
let fd = new FormData()
fd.append('name', '张三')
fd.append('uploadFile', file对象)
axios.post('/upload', fd)
上传的图片如何访问?
摸清楚这些图片存哪个文件夹了?这个文件夹有没有开放给客户端访问权限?如果开放了,该如何访问?
public下。express已经将public作为了静态资源托管目录。所以可以如下路径来访问1f319097-5952-4d55-b58e-7a230.png图片: http://localhost:3000/1f319097-5952-4d55-b58e-7a230.png
上传头像完整流程
构建数据表:
id name age avatar 1 zs 15 a.jpg 2 ls 13 b.jpg .. .. .. ..
客户端选择新头像文件,点击(拖拽)上传。一旦上传成功,需要将头像重命名后存入upload文件夹,并且更新数据库中当前用户的头像路径。
id name age avatar 1 zs 15 qwr6q-qrer-rqwerwe-qwerw.jpg 2 ls 13 b.jpg .. .. .. ..
等下次用户登录时,将会获取数据库中的全新的用户信息,从而拿到最新的头像路径,拼接成完整路径后访问新头像即可。
axios上传文件刷新页面?
上传图片用户是axios,axios底层基于ajax,众所周知,ajax是一个异步发送请求局部更新页面的技术,理论上来讲不会刷新页面的,但是实际上传文件时发现页面上传完毕后竟然刷新了。 若在跨域的情况下发送axios请求上传文件,将会刷新页面。可以构造一个不跨域的请求,就可以异步上传文件了。 将upload.html与axios.js放到upload目录下,称为3000端口下应用的静态资源进行访问: http://localhost:3000/03_upload.html
websocket
websocket可以实现客户端与服务端的数据的实时通信。(长连接)
网络通信过程中的长连接与短连接
短连接: 客户端与服务端建立连接,客户端发送请求,服务端接收请求,处理请求,返回响应;客户端接收响应数据后连接断开。这种通讯模式称为短连接。HTTP协议是基于短连接的协议。
长连接:客户端与服务端建立连接,客户端发送请求,服务端接收请求,处理请求,返回响应;客户端接收响应数据后连接不断开。服务端可以随时使用这个连接向客户端自发的发消息。这种通讯模式称为长连接。websocket就基于长连接。
什么是websocket?
websocket是一种在单个TCP连接上进行全双工通信(通讯过程允许两个方向上通信完成数据传输)的一种通信协议。是一款长连接协议。
如何使用代码建立websocket连接并实现通信?
socket.io
socket.io是一个为浏览器与服务器之间提供实时的, 双向的, 基于事件通信的网络通信库。 它实现了websocket协议,提供了相关API。抹平了一些技术细节及浏览器兼容性。
//html页面中 导入socket.io.js之后
io('ws://ip:port/')
//nodejs服务端接收
require('socket.io')
socketio.on('connection', (socket)=>{
连接成功, 开始通信
})
建立websocket连接
服务端
创建nodejs项目socketserver。
安装socket.io、express模块。
# 进入socketserver目录后执行以下命令
cd socketserver
npm init # 初始化npm项目,一路回车即可
npm install --save socket.io
npm install --save express
新建index.js,编写后端代码,监听客户端的连接。
//index.js
const http = require('http').createServer()
const socketio = require('socket.io')(http)
// 监听connection事件,一旦有客户端连接成功就会触发该事件,
// 执行回调方法,传入一个socket对象用于与当前客户端进行数据交互
socketio.on('connection', (socket)=>{
console.log('有客户端进来啦:'+socket.id)
})
http.listen(3000, ()=>{
console.log('server is running...')
})
客户端
新建html页面。引入socket.io.js。 调用io()方法与正在监听的服务端建立连接。
注意:若使用前后端分离架构建立websocket连接,高版本socket.io将会出现跨域问题,如下配置即可:
const socketio = require('socket.io')(http, {
cors: {
origin: "*",
credentials: true
}
})
客户端服务端之间进行通信
客户端向服务端发消息
客户端发送消息
let socket = io('ws://localhost:3000/')
socket.emit('TextMsg', '你瞅啥?') // (消息类型,消息内容)
服务端接收消息
socketio.on('connection', (socket)=>{
socket.on('TextMsg', (data)=>{
console.log(data)
})
})
服务端向客户端发消息
服务端发送消息:
socketio.on('connection', (socket)=>{
socket.emit('TextMsg', '瞅你咋地~~~~~~')
})
客户端接收消息:
let socket = io('ws://localhost:3000/')
socket.on('TextMsg', (res)=>{
alert('服务端回复:'+res)
})
服务端向所有在线的客户端广播消息
socketio.on('connection', (socket)=>{
socketio.emit('TextMsg', '瞅你咋地~~~~~~')
})
群聊天室
1.完成核心的群聊功能。在textarea中输入文本内容,点击发表,发送消息,该消息可以让所有在线的客户端都看到。显示在聊天记录区。
在chart.html页面加载时,直接建立websocket连接。
为发表按钮绑定click事件处理方法,点击按钮后,获取textarea中的值,发给服务端。
服务端接收该文本消息,将该文本消息给所有客户端都发一遍。
客户端监听服务端发回来的文本消息,一旦接收到,显示在聊天记录区。
完成在线人数的统计。
2.在app.js中声明一个 全局变量count用于保存当前在线人数。
当监听到有个客户端连接,那么count++
当监听到有客户端断开连接,那么count--
无论count有何种变化,只要一更新就需要向所有客户端都发一个消息:emit('CountMsg', count)。
客户端接收消息,更新span即可。
实现登录业务。
3.在index.html中点击登录按钮(绑定click事件),生成一个头像文件名,获取用户昵称,跳转到chart.html页面并且传递这两个参数。
在chart.html页面加载时,从请求路径中解析出name与avatar参数,更新界面。
在发送是携带name与avatar一起发送即可。
群聊天室
1.完成核心的群聊功能。在textarea中输入文本内容,点击发表,发送消息,该消息可以让所有在线的客户端都看到。显示在聊天记录区。
在chart.html页面加载时,直接建立websocket连接。
为发表按钮绑定click事件处理方法,点击按钮后,获取textarea中的值,发给服务端。
服务端接收该文本消息,将该文本消息给所有客户端都发一遍。
客户端监听服务端发回来的文本消息,一旦接收到,显示在聊天记录区。
完成在线人数的统计。
2.在app.js中声明一个 全局变量count用于保存当前在线人数。
当监听到有个客户端连接,那么count++
当监听到有客户端断开连接,那么count--
无论count有何种变化,只要一更新就需要向所有客户端都发一个消息:emit('CountMsg', count)。
客户端接收消息,更新span即可。
3.实现登录业务。
在index.html中点击登录按钮(绑定click事件),生成一个头像文件名,获取用户昵称,跳转到chart.html页面并且传递这两个参数。
在chart.html页面加载时,从请求路径中解析出name与avatar参数,更新界面。
在发送是携带name与avatar一起发送即可。
上线
将写好的程序部署到一个拥有外网ip地址的服务器。 这样才可以保证全球用户外网访问。
WebWorker
WebWorker可以为Javascript提供多线程环境,通过主线程创建worker线程,可以将繁重的工作交给worker线程来实现,从而减轻主线程的工作压力。
Javascript默认采用的是单线程模型,所有的任务都会在主线程中执行。而主线程有一个非常重要的任务:不间断的绘制UI。所以主线程不能有一丝耗时代码的执行,否则将会阻塞主线程绘制UI,导致界面卡顿。
HTML提供了webworker来帮助主线程分担耗时任务的执行。让主线程专心绘制界面。
案例:感受一下耗时代码。
1 1 2 3 5 8 13 21 34 55 89 .....
function fb(n){
return n<3 ? 1 : fb(n-1) + fb(n-2)
}
WebWorker的基本使用
创建一个WebWorker,将耗时代码搬到worker线程中异步执行,这样,就不会影响主线程的UI绘制。基本写法如下:
新建一个worker.js,将耗时代码写在这里。
在主线程中,需要执行耗时代码时,如下创建worker
let mworker = new Worker('./worker.js')
虽然上述代码可以在worker线程中异步执行耗时任务,但是工作中要尽量避免过多的创建worker,将会导致系统卡顿。建议创建一个worker,工作可以交给这一个worker顺序执行。
-
创建
worker。 -
给
worker发消息,让worker执行耗时任务。
Worker与主线程的通信
主线程给worker线程发消息
主线程发消息:
let mworker = new Worker('./worker.js')
mworker.postMessage('消息内容') // 发消息
worker线程接收消息:
//worker.js
function fb(n){ ... }
onmessage = (e)=>{ fb(xx) }
worker线程给主线程发消息
worker发消息:
//worker.js
function fb(n){ ... }
postMessage('消息内容')
主线程接收消息:
let w = new Worker('./worker2.js')
w.onmessage = (e)=>{
e.data
document.getElementXXXXXXX()
}
SVG
什么是SVG?
SVG(Scalable Vector Graphics)可伸缩的矢量图形。是基于XML语法的一种图像格式。这种图像通过XML标签语言来进行绘制。浏览器会根据svg标准对xml文本进行解析,从而显示图像。
第一个SVG图像
案例:在200*200的svg画布上,画一个圆。
-
新建文件:
circle.svg. 编写svg标签源代码。 -
在
html中引入该svg即可。<img src="./circle.svg">
SVG的使用场景
第一种用法:
<img src="a.svg">
第二种用法:
<body>
<svg>
<circle ..../>
</svg>
</body>
第三种使用方法:
<div style="background-image:url('./a.svg')"></div>
Echarts
ECharts示例
-
下载
echarts。 -
新建
html, 引入echarts。 -
新建div作为图表 容器,执行
init()初始化echarts图表,调用setOption()方法 设置显示图表。 -
# `HTML5`新特性 `Unit07`
## `Echarts`
`echarts`是百度开源的数据可视化工具,基于`javascript`,可以在浏览器或移动端显示美观的图表。
`ECharts`示例
1. 下载`echarts`。
2. 新建`html`, 引入`echarts`。
3. 新建div作为图表 容器,执行`init()`初始化`echarts`图表,调用`setOption()`方法 设置显示图表。
```javascript
name: zs
pwd: 1234
`select * from user
where name='${name}' and pwd='${pwd}'`
`select * from user
where name='zs' and pwd='1234'`
name: zs
pwd: 1' or '1'='1
`select * from user
where name='zs' and pwd='1' or '1'='1'`
### `HTTP`协议的状态管理
由于`HTTP`协议是一款短连接的协议,所以`http`请求具有无状态的特点。即同一个客户端发送的多次请求并没有当做一个整体来看待。所以急需想一些办法将这些独立的请求当做一个整体,即将同一个客户端发送的多次请求涉及到的数据保存下来。这就叫做`http`的状态管理。
`http`的状态管理有3种解决方案:
1. `cookie`
2. `session`
3. `token` 详见视频。
jwt 链接:https://pan.baidu.com/s/1B3YUiJnd3A2vOGKmkEu0_Q
提取码:2prs

浙公网安备 33010602011771号