HTML5存储,多线程和websocket,聊天室,Web workers使得2件事同时进行【诗书画唱】


导读:
HTML5-5Input标签.ppt
HTML5-6Web存储.ppt
localStorage和sessionStorage,都可以调用以下的方法:
保存数据:setItem(key,value);
读取数据:getItem(key);
删除单个数据:removeItem(key);
删除所有数据:clear();
得到某个索引的key:key(index);
HTML5-7Web workers.ppt
HTML5-8Websocket.ppt
H5存储对象,把账号密码等存储到localStorage.html
//尝试将localStorage中的账号和密码自动填充到输入框中
document.getElementById('act').value = localStorage.getItem('zhh');
document.getElementById('pwd').value = localStorage.getItem('mm');
chk.checked
localStorage.setItem('zhh',act);
localStorage.setItem('mm',pwd);
sessionStorage传数据,共享临时数据的方法(也要跳转到要传的界面)
localStorage 和 sessionStorage 属性允许在浏览器中存储 key/value 对的数据。
sessionStorage 用于临时保存同一窗口(或标签页)的数据,在关闭窗口或标签页之后将会删除这些数据。
提示: 如果你想在浏览器窗口关闭后还保留数据,可以使用 localStorage 属性, 该数据对象没有过期时间,今天、下周、明年都能用,除非你手动去删除。
alert是我常用来测试出BUG的弹出框
讲义
个人对Web Workers的理解:
Web Workers类似Ajax和多线程的效果,就是解决了一种程序未
执行完之前,用户无法去同时执行另一个操作(比如
这个例子中如果没用Web Workers,有个在控制台打印
1到很大的数字的程序(或一个网站加载大的图片时),如果没执行完
那么是无法使用搜索框的,无法输入,造成一种“卡”的感觉,这样的话用户体验很差,会流失用户。
检测浏览器是否支持XXX
if(typeof(XXX) !== 'undefined')
比如:检测浏览器是否支持WEBWORKER
if(typeof(Worker) !== 'undefined')
检测浏览器是否支持Storage
if(typeof(Storage) !== 'undefined')
postMessage和onmessage是HTML5的方法,用来解决跨页面通信,或者通过iframe嵌套的不同页面的通信的。postMessage为发送方,onmessage为接收方。
推荐:
https://www.cnblogs.com/super-yu/p/9480589.html

个人理解:“XX.onmessage等方法 = function(XXX){}”是一种绑定onmessage等方法在XX上的方法,还传了XXX的值。
当在HTML页面中执行脚本直到脚本运行结束,页面会呈现卡死状态。Web Worker是运行在后台的JavaScript,独立于其他脚本,不会影响页面的性能。我们可以在Web Worker脚本运行的同时做任何愿意做的事情:点击、选取内容等等,而此时Web Worker在后台运行。
使用Web Workers可以实现JS版本的多线程。
当我们创建Web Worker对象后,它会继续监听消息(即使在外部脚本完成之后)直到其被终止为止。
如需终止 web worker,并释放浏览器/计算机资源,请使用 terminate() 方法(谨慎使用,因为很这个方法可能很耗费资源)
个人理解:服务端就是后台,是服务于客户端的界面操作的,后台的管理员负责开启服务器。
聊天室
sw和nickname可以统一(包括相关的
java和html文件中的内容)地改变成别的变量
要注意端口号,有些人的端口号是不同的(比如我的是8080,有些是8888,涉及访问路径的Java Web相关的程序如果端口号不对,就会访问出错等等)
要统一或获取端口号
停止等待协议
“SW”的全称为“stop-and-wait”,表示停止等待协议,停止等待协议是最简单但也是最基础的数据链路层协议,主要用于数据的可靠传输。停止等待就是每发送完一个分组就停止发送,等待对方的确认。在收到确认后再发送下一个分组。
留给读者思考的作业
洗一个茶杯需要3秒,总共洗5个(每隔3秒打印洗了第i个茶杯),烧开水需要10秒(10秒后打印水烧开了),请编写一个程序,让上面两个任务同时运行。

HTML5-5Input标签.ppt START


color:选取颜色
date:选择日期
email:表单提交时自动验证邮件格式
number:数值输入的范围(max和min属性)
range:滑块选择范围数值(max和min属性)
url:表单提交时自动验证是否是合法的url格式
HTML5-5Input标签.ppt END
HTML5-6Web存储.ppt START






localStorage和sessionStorage,都可以调用以下的方法:
保存数据:setItem(key,value);
读取数据:getItem(key);
删除单个数据:removeItem(key);
删除所有数据:clear();
得到某个索引的key:key(index);
HTML5-6Web存储.ppt END
HTML5-7Web workers.ppt START







HTML5-7Web workers.ppt END
HTML5-8Websocket.ppt START


HTML5-8Websocket.ppt END
讲义 START

讲义 END
H5存储对象,把账号密码等存储到localStorage.html START
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
*{
font-size: 50px;
}
</style>
<script>
window.onload = function(){
//尝试将localStorage中的账号和密码自动填充到输入框中
document.getElementById('act').value = localStorage.getItem('zhh');
document.getElementById('pwd').value = localStorage.getItem('mm');
document.getElementById('btn').onclick = function(){
//判断记住密码选项是否被勾选
var chk = document.getElementById('rmpwd');
if(chk.checked) {
//如果被勾选,就将输入的账号和密码永久的保存下来
var act = document.getElementById('act').value;
var pwd = document.getElementById('pwd').value;
if(typeof(Storage) !== 'undefined') {
//将账号和密码永久的保存到localStorage中
localStorage.setItem('zhh',act);
localStorage.setItem('mm',pwd);
}
} else {
//如果没有选中记住密码选项,就要移除掉这两个数据
localStorage.removeItem('zhh');
localStorage.removeItem('mm');
}
}
}
</script>
</head>
<body>
<label>账号:</label>
<input type="text" id="act" />
<br>
<br>
<label>密码:</label>
<input type="password" id="pwd" />
<br>
<br>
<label>记住密码</label>
<input type="checkbox" id="rmpwd" checked />
<br>
<br>
<input id="btn" type="button" value="登录" />
</body>
</html>



H5存储对象,把账号密码等存储到localStorage.html END
sessionStorage传数据,共享临时数据的方法(也要跳转到要传的界面) START
localStorage 和 sessionStorage 属性允许在浏览器中存储 key/value 对的数据。
sessionStorage 用于临时保存同一窗口(或标签页)的数据,在关闭窗口或标签页之后将会删除这些数据。
提示: 如果你想在浏览器窗口关闭后还保留数据,可以使用 localStorage 属性, 该数据对象没有过期时间,今天、下周、明年都能用,除非你手动去删除。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script>
if(typeof(Storage) !== 'undefined') {
sessionStorage.setItem('userName','给诗书画唱三连关注!');
//alert(sessionStorage.getItem('userName'));
window.location.href = 'test.html';
}
</script>
</head>
<body>
</body>
</html>

alert是我常用来测试出BUG的弹出框

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script>
window.onload = function(){
if(typeof(Storage) !== 'undefined') {
document.getElementById('inp').value
= sessionStorage.userName;
}
}
</script>
</head>
<body>
<input type="text" id="inp" />
</body>
</html>


sessionStorage传数据,共享临时数据的方法(也要跳转到要传的界面) END
有多线程,可同时进行多个操作的效果,解决卡顿问题的Web Workers运用 START




<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
*{
font-size: 50px;
}
</style>
<script>
window.onload = function(){
var w;
//检测浏览器是否支持WEBWORKER
if(typeof(Worker) !== 'undefined') {
if(typeof(w) === 'undefined') {
//需要执行的代码放到de.js文件中
w = new Worker('js/de.js');
}
//调用postMessage方法时,
//会触发这个onmessage事件绑定的函数
w.onmessage = function(e){
//e.data就是postMessage方法中的变量i
document.getElementById('num').innerHTML = e.data;
}
}
}
</script>
</head>
<body>
<input type="text" />
<div id="num"></div>
</body>
</html>



有多线程,可同时进行多个操作的效果,解决卡顿问题的Web Workers运用 END
聊天室 START

/**
* CTRL+F:
*
* 单词:nickname昵称
* synchronized同步
* socket插座
* onlineCount在线数量
* sub:借;替换
* “SW”的全称bai为“stop-and-wait”,
* 表示停止等待协议,停du止等待协议是最简单但也是
* 最基础的数据链路层协议,主要用于数据的可靠传输。
* 停止等待就是每发送完一个分组就停止发送
* ,等待对方的确认。在收到确认后再发送下一个分组。
* */
package LiaoTianShi;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.concurrent.CopyOnWriteArraySet;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
//{nickname}相当于一个占位符
@ServerEndpoint("/sw/{nickname}")
/*这里的sw和nickname可以统一(包括相关的
java和html文件中的内容)地改变成别的变量
要注意端口号,有些人的端口号是不同的(比如我的是8080,有些是8888,涉及访问路径的Java Web相关的程序如果端口号不对,就会访问出错等等)
要统一或获取端口号*/
public class ServWebSocket {
//聊天在线人数
private static Integer onlineCount = 0;
//存放所有在线客户的集合
private static CopyOnWriteArraySet<ServWebSocket>swSet
= new CopyOnWriteArraySet<ServWebSocket>();
//客户连接的会话对象
private Session session;
//获取聊天室中的在线人数
public static synchronized Integer getOnlineCount(){
return ServWebSocket.onlineCount;
}
//当一个用户进入聊天室时,在线人数加1
public static synchronized void addOnlineCount(){
ServWebSocket.onlineCount ++;
}
//当一个用户退出聊天室时,在线人数减1
public static synchronized void subOnlineCount(){
ServWebSocket.onlineCount --;
}
//当用户成功进入到聊天室时调用的方法
@OnOpen
/*"@PathParam("nickname")String nn"表示:"nn"的值跟
"/sw/{nickname}"中的"{nickname}"一致*/
public void onOpen(Session s,@PathParam("nickname")String nn){
this.session = s;
//将当前进入聊天室的用户存放到set中
swSet.add(this);
//在线人数加1
addOnlineCount();
try {
//nn如果是中文,需要做中文乱码处理
nn = new String(nn.getBytes("iso8859-1"),"utf-8");
System.out.println(nn + "进入了聊天室,当前在线人数:"
+ getOnlineCount());
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//当用户下线时调用的方法
@OnClose
public void onClose(@PathParam("nickname")String nn){
//将当前的用户移除掉
swSet.remove(this);
//在线人数减1
subOnlineCount();
//通过循环告诉聊天室中的其他用户,当前用户下线了
for(ServWebSocket user : swSet) {
//乱码处理
try {
nn = new String(nn.getBytes("iso8859-1"),"utf-8");
//对其他的用户发送消息,当前用户下线啦
user.sendMsg(nn + "离开了聊天室。");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//发送消息到其他的用户
private void sendMsg(String msg){
try {
this.session.getBasicRemote().sendText(msg);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//当用户发送消息给服务端时调用的方法
//msg:需要发送的消息内容
//s:当前用户的会话对象
@OnMessage
public void onMessage(String msg,Session s){
System.out.println("来自于" + s.getId() + "用户发送的消息是:" + msg);
//让发送的消息能够让所有的用户都看到
//获取发送消息的用户的昵称
String nickname = s.getPathParameters().get("nickname");
try {
//对昵称进行乱码处理
nickname = new String(nickname.getBytes("iso8859-1"),"utf-8");
//在线的其他用户发送当前用户说的话
for(ServWebSocket user : swSet) {
user.sendMsg(nickname + "说:" + msg);
}
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//连接聊天室时发生错误时调用的方法
@OnError
public void onError(Session s,Throwable error){
System.out.println("进入聊天室时发生错误");
//打印出错误的原因
error.printStackTrace();
}
}


<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
*{
font-size: 50px;
}
</style>
<script>
window.onload = function(){
//创建一个WebSocket对象
var websocket = null;
//检测浏览器是否支持websocket
if('WebSocket' in window) {
//以爱国者的昵称连接聊天室
//无论是什么时候都要注意端口号的统一,我的是8080
websocket = new WebSocket('ws://127.0.0.1:8080/HTML5websocke/sw/诗书画唱');
} else {
console.log('你的浏览器不支持websocket');
}
//定义显示聊天信息的方法
function setHtml(html){
document.getElementById('message').innerHTML
+= html + '<br>';
}
//进入到聊天室时执行的代码
websocket.onopen = function(){
setHtml('聊天室连接成功')
}
function sendMsg(){
//获取输入文本框中需要发送到聊天室中的消息
var msg = document.getElementById('chat').value;
//发送消息
websocket.send(msg);
}
//给发送按钮绑定事件
document.getElementById('sendBtn').onclick = sendMsg;
//当接收到服务端的消息时,需要执行的代码
websocket.onmessage = function(e){
//将消息显示出来
setHtml(e.data);
}
//有人下线时调用
websocket.onclose = function(){
setHtml('有人下线啦!');
}
//进入聊天室发生错误时调用
websocket.onerror = function(){
setHtml('发生错误啦');
}
//当窗口关闭时,主动关闭websocket连接
window.onbeforeunload = function(){
websocket.close();
}
document.getElementById('ulBtn').onclick = function(){
websocket.close();
}
}
</script>
</head>
<body>
<div style="text-align: center;">
<input type="text" id="chat" />
<input type="button" value="发送" id="sendBtn"/>
<input type="button" value="下线" id="ulBtn"/>
<div id="message"></div>
</div>
</body>
</html>












点击后:


聊天室 END
留给读者思考的作业 START
1、实现输入账号密码后能够保存账号密码的功能。(答案见上面的内容)
2、洗一个茶杯需要3秒,总共洗5个(每隔3秒打印洗了第i个茶杯),烧开水需要10秒(10秒后打印水烧开了),请编写一个程序,让上面两个任务同时运行。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<!-- web worker是运行在后台的javascript,不会影响页面的性能 -->
<p><output id="result"></output></p>
<p><output id="result2"></output></p>
<button onclick="startWorker()">开始worker</button>
<button onclick="endWorker()">停止worker</button>
<div id='ceshi' onclick="ceshi()">点击我不会阻塞代码</div>
<br><br>
<script type="text/javascript">
var w;
function startWorker(){
if(typeof(Worker)!="undefined"){//浏览器支持web worker
if(typeof(w)=="undefined"){//w是未定义的,还没有开始计数
w = new Worker("webworker.js");//创建一个Worker对象,利用Worker的构造函数
w2 = new Worker("webworker2.js");//创建一个Worker对象,利用Worker的构造函数
}
//onmessage是Worker对象的properties
w.onmessage = function(event){//事件处理函数,用来处理后端的web worker传递过来的消息
document.getElementById("result").innerHTML="洗了第"+event.data+"个杯子";
if(event.data=="5"){w.terminate();//利用Worker对象的terminated方法,终止
w=undefined; }
};
w2.onmessage = function(event){//事件处理函数,用来处理后端的web worker传递过来的消息
document.getElementById("result2").innerHTML=event.data;
};
}else{
document.getElementById("result").innerHTML="sorry,your browser does not support web workers";
document.getElementById("result2").innerHTML="sorry,your browser does not support web workers";
}
}
function endWorker(){
w.terminate();//利用Worker对象的terminated方法,终止
w=undefined;
w2.terminate();//利用Worker对象的terminated方法,终止
w2=undefined;
}
function ceshi(){
console.log(555)
}
</script>
</body>
</html>


var i = 0;
function timeCount(){
setTimeout("timeCount()",3000);//定时任务
i = i + 1;
postMessage(i);//postMessage是Worker对象的方法,用于向html页面回传一段消息
}
timeCount();//加1计数,每500毫秒调用一次


var i = 0;
function timeCount2(){
setTimeout("timeCount2()",1000);//定时任务
i = i+1;
if(i==10){ postMessage("水烧开了!");//postMessage是Worker对象的方法,用于向html页面回传一段消息
}
}
timeCount2();//加1计数,每500毫秒调用一次

推荐:https://blog.csdn.net/xyf_coco/article/details/80606731
3、实现聊天室功能(答案见上面的内容)
留给读者思考的作业 END