HTML5存儲,多線程和websocket,聊天室,Web workers使得2件事同時(shí)進(jìn)行【詩書畫唱】


導(dǎo)讀:
HTML5-5Input標(biāo)簽.ppt
HTML5-6Web存儲.ppt
localStorage和sessionStorage,都可以調(diào)用以下的方法:
保存數(shù)據(jù):setItem(key,value);
讀取數(shù)據(jù):getItem(key);
刪除單個(gè)數(shù)據(jù):removeItem(key);
刪除所有數(shù)據(jù):clear();
得到某個(gè)索引的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傳數(shù)據(jù),共享臨時(shí)數(shù)據(jù)的方法(也要跳轉(zhuǎn)到要傳的界面)
localStorage 和 sessionStorage 屬性允許在瀏覽器中存儲 key/value 對的數(shù)據(jù)。
sessionStorage 用于臨時(shí)保存同一窗口(或標(biāo)簽頁)的數(shù)據(jù),在關(guān)閉窗口或標(biāo)簽頁之后將會刪除這些數(shù)據(jù)。
提示:?如果你想在瀏覽器窗口關(guān)閉后還保留數(shù)據(jù),可以使用?localStorage?屬性, 該數(shù)據(jù)對象沒有過期時(shí)間,今天、下周、明年都能用,除非你手動去刪除。
alert是我常用來測試出BUG的彈出框
講義
個(gè)人對Web Workers的理解:
Web Workers類似Ajax和多線程的效果,就是解決了一種程序未
執(zhí)行完之前,用戶無法去同時(shí)執(zhí)行另一個(gè)操作(比如
這個(gè)例子中如果沒用Web Workers,有個(gè)在控制臺打印
1到很大的數(shù)字的程序(或一個(gè)網(wǎng)站加載大的圖片時(shí)),如果沒執(zhí)行完
那么是無法使用搜索框的,無法輸入,造成一種“卡”的感覺,這樣的話用戶體驗(yàn)很差,會流失用戶。
檢測瀏覽器是否支持XXX
if(typeof(XXX) !== 'undefined')
比如:檢測瀏覽器是否支持WEBWORKER
if(typeof(Worker) !== 'undefined')
檢測瀏覽器是否支持Storage
if(typeof(Storage) !== 'undefined')?
postMessage和onmessage是HTML5的方法,用來解決跨頁面通信,或者通過iframe嵌套的不同頁面的通信的。postMessage為發(fā)送方,onmessage為接收方。
推薦:
https://www.cnblogs.com/super-yu/p/9480589.html

個(gè)人理解:“XX.onmessage等方法 = function(XXX){}”是一種綁定onmessage等方法在XX上的方法,還傳了XXX的值。
當(dāng)在HTML頁面中執(zhí)行腳本直到腳本運(yùn)行結(jié)束,頁面會呈現(xiàn)卡死狀態(tài)。Web Worker是運(yùn)行在后臺的JavaScript,獨(dú)立于其他腳本,不會影響頁面的性能。我們可以在Web Worker腳本運(yùn)行的同時(shí)做任何愿意做的事情:點(diǎn)擊、選取內(nèi)容等等,而此時(shí)Web Worker在后臺運(yùn)行。
使用Web Workers可以實(shí)現(xiàn)JS版本的多線程。
當(dāng)我們創(chuàng)建Web Worker對象后,它會繼續(xù)監(jiān)聽消息(即使在外部腳本完成之后)直到其被終止為止。
如需終止 web worker,并釋放瀏覽器/計(jì)算機(jī)資源,請使用 terminate() 方法(謹(jǐn)慎使用,因?yàn)楹苓@個(gè)方法可能很耗費(fèi)資源)
個(gè)人理解:服務(wù)端就是后臺,是服務(wù)于客戶端的界面操作的,后臺的管理員負(fù)責(zé)開啟服務(wù)器。
聊天室
sw和nickname可以統(tǒng)一(包括相關(guān)的
java和html文件中的內(nèi)容)地改變成別的變量
要注意端口號,有些人的端口號是不同的(比如我的是8080,有些是8888,涉及訪問路徑的Java Web相關(guān)的程序如果端口號不對,就會訪問出錯(cuò)等等)
要統(tǒng)一或獲取端口號
停止等待協(xié)議
“SW”的全稱為“stop-and-wait”,表示停止等待協(xié)議,停止等待協(xié)議是最簡單但也是最基礎(chǔ)的數(shù)據(jù)鏈路層協(xié)議,主要用于數(shù)據(jù)的可靠傳輸。停止等待就是每發(fā)送完一個(gè)分組就停止發(fā)送,等待對方的確認(rèn)。在收到確認(rèn)后再發(fā)送下一個(gè)分組。
留給讀者思考的作業(yè)
洗一個(gè)茶杯需要3秒,總共洗5個(gè)(每隔3秒打印洗了第i個(gè)茶杯),燒開水需要10秒(10秒后打印水燒開了),請編寫一個(gè)程序,讓上面兩個(gè)任務(wù)同時(shí)運(yùn)行。

HTML5-5Input標(biāo)簽.ppt START


color:選取顏色
date:選擇日期
email:表單提交時(shí)自動驗(yàn)證郵件格式
number:數(shù)值輸入的范圍(max和min屬性)
range:滑塊選擇范圍數(shù)值(max和min屬性)
url:表單提交時(shí)自動驗(yàn)證是否是合法的url格式
HTML5-5Input標(biāo)簽.ppt END
HTML5-6Web存儲.ppt START






localStorage和sessionStorage,都可以調(diào)用以下的方法:
保存數(shù)據(jù):setItem(key,value);
讀取數(shù)據(jù):getItem(key);
刪除單個(gè)數(shù)據(jù):removeItem(key);
刪除所有數(shù)據(jù):clear();
得到某個(gè)索引的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(){
//判斷記住密碼選項(xiàng)是否被勾選
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 {
//如果沒有選中記住密碼選項(xiàng),就要移除掉這兩個(gè)數(shù)據(jù)
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傳數(shù)據(jù),共享臨時(shí)數(shù)據(jù)的方法(也要跳轉(zhuǎn)到要傳的界面) START
localStorage 和 sessionStorage 屬性允許在瀏覽器中存儲 key/value 對的數(shù)據(jù)。
sessionStorage 用于臨時(shí)保存同一窗口(或標(biāo)簽頁)的數(shù)據(jù),在關(guān)閉窗口或標(biāo)簽頁之后將會刪除這些數(shù)據(jù)。
提示:?如果你想在瀏覽器窗口關(guān)閉后還保留數(shù)據(jù),可以使用?localStorage?屬性, 該數(shù)據(jù)對象沒有過期時(shí)間,今天、下周、明年都能用,除非你手動去刪除。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script>
if(typeof(Storage) !== 'undefined') {
sessionStorage.setItem('userName','給詩書畫唱三連關(guān)注!');
//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傳數(shù)據(jù),共享臨時(shí)數(shù)據(jù)的方法(也要跳轉(zhuǎn)到要傳的界面) END
有多線程,可同時(shí)進(jìn)行多個(gè)操作的效果,解決卡頓問題的Web Workers運(yùn)用 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') {
//需要執(zhí)行的代碼放到de.js文件中
w = new Worker('js/de.js');
}
//調(diào)用postMessage方法時(shí),
//會觸發(fā)這個(gè)onmessage事件綁定的函數(shù)
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>



有多線程,可同時(shí)進(jìn)行多個(gè)操作的效果,解決卡頓問題的Web?Workers運(yùn)用 END
聊天室 START

/**
* CTRL+F:
*?
* 單詞:nickname昵稱
* synchronized同步
* socket插座
* onlineCount在線數(shù)量
* sub:借;替換
* “SW”的全稱bai為“stop-and-wait”,
* 表示停止等待協(xié)議,停du止等待協(xié)議是最簡單但也是
* 最基礎(chǔ)的數(shù)據(jù)鏈路層協(xié)議,主要用于數(shù)據(jù)的可靠傳輸。
* 停止等待就是每發(fā)送完一個(gè)分組就停止發(fā)送
* ,等待對方的確認(rèn)。在收到確認(rèn)后再發(fā)送下一個(gè)分組。
* */
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}相當(dāng)于一個(gè)占位符
@ServerEndpoint("/sw/{nickname}")
/*這里的sw和nickname可以統(tǒng)一(包括相關(guān)的
java和html文件中的內(nèi)容)地改變成別的變量
要注意端口號,有些人的端口號是不同的(比如我的是8080,有些是8888,涉及訪問路徑的Java Web相關(guān)的程序如果端口號不對,就會訪問出錯(cuò)等等)
要統(tǒng)一或獲取端口號*/
public class ServWebSocket {
//聊天在線人數(shù)
? ? private static Integer onlineCount = 0;
? ? //存放所有在線客戶的集合
? ? private static CopyOnWriteArraySet<ServWebSocket>swSet?
? ? ? ? = new CopyOnWriteArraySet<ServWebSocket>();
? ? //客戶連接的會話對象
? ? private Session session;
? ??
? ? //獲取聊天室中的在線人數(shù)
? ? public static synchronized Integer getOnlineCount(){
? ? return ServWebSocket.onlineCount;
? ? }
? ??
? ? //當(dāng)一個(gè)用戶進(jìn)入聊天室時(shí),在線人數(shù)加1
? ? public static synchronized void addOnlineCount(){
? ? ServWebSocket.onlineCount ++;?
? ? }
? ??
? ? //當(dāng)一個(gè)用戶退出聊天室時(shí),在線人數(shù)減1
? ? public static synchronized void subOnlineCount(){
? ? ServWebSocket.onlineCount --;?
? ? }
? ??
? ? //當(dāng)用戶成功進(jìn)入到聊天室時(shí)調(diào)用的方法
? ? @OnOpen
? ? /*"@PathParam("nickname")String nn"表示:"nn"的值跟
? ? "/sw/{nickname}"中的"{nickname}"一致*/
? ? public void onOpen(Session s,@PathParam("nickname")String nn){
? ? this.session = s;
? ? //將當(dāng)前進(jìn)入聊天室的用戶存放到set中
? ? swSet.add(this);
? ? //在線人數(shù)加1
? ? addOnlineCount();? ?
? ? try {
? ? ? ? //nn如果是中文,需要做中文亂碼處理
nn = new String(nn.getBytes("iso8859-1"),"utf-8");
System.out.println(nn + "進(jìn)入了聊天室,當(dāng)前在線人數(shù):"?
? ? + getOnlineCount());
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
? ? }
? ??
? ? //當(dāng)用戶下線時(shí)調(diào)用的方法
? ? @OnClose
? ? public void onClose(@PathParam("nickname")String nn){
? ? //將當(dāng)前的用戶移除掉
? ? swSet.remove(this);
? ? //在線人數(shù)減1
? ? subOnlineCount();
? ? //通過循環(huán)告訴聊天室中的其他用戶,當(dāng)前用戶下線了
? ? for(ServWebSocket user : swSet) {
? ? //亂碼處理
? ? try {
nn = new String(nn.getBytes("iso8859-1"),"utf-8");
//對其他的用戶發(fā)送消息,當(dāng)前用戶下線啦
user.sendMsg(nn + "離開了聊天室。");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
? ? }
? ? }
? ? //發(fā)送消息到其他的用戶
? ? private void sendMsg(String msg){
? ? try {
this.session.getBasicRemote().sendText(msg);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
? ? }
? ??
? ? //當(dāng)用戶發(fā)送消息給服務(wù)端時(shí)調(diào)用的方法
? ? //msg:需要發(fā)送的消息內(nèi)容
? ? //s:當(dāng)前用戶的會話對象
? ? @OnMessage
? ? public void onMessage(String msg,Session s){
? ? System.out.println("來自于" + s.getId() + "用戶發(fā)送的消息是:" + msg);
? ? //讓發(fā)送的消息能夠讓所有的用戶都看到
? ? //獲取發(fā)送消息的用戶的昵稱
? ? String nickname = s.getPathParameters().get("nickname");
? ? try {
? ? //對昵稱進(jìn)行亂碼處理
nickname = new String(nickname.getBytes("iso8859-1"),"utf-8");
//在線的其他用戶發(fā)送當(dāng)前用戶說的話
? ? for(ServWebSocket user : swSet) {
? ? user.sendMsg(nickname + "說:" + msg);
? ? }
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
? ? }
? ??
? ? //連接聊天室時(shí)發(fā)生錯(cuò)誤時(shí)調(diào)用的方法
? ? @OnError
? ? public void onError(Session s,Throwable error){
? ? System.out.println("進(jìn)入聊天室時(shí)發(fā)生錯(cuò)誤");
? ? //打印出錯(cuò)誤的原因
? ? error.printStackTrace();
? ? }? ??
}


<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
*{
font-size: 50px;
}
</style>
<script>
window.onload = function(){
//創(chuàng)建一個(gè)WebSocket對象
var websocket = null;
//檢測瀏覽器是否支持websocket
if('WebSocket' in window) {
//以愛國者的昵稱連接聊天室
//無論是什么時(shí)候都要注意端口號的統(tǒng)一,我的是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>';
}
//進(jìn)入到聊天室時(shí)執(zhí)行的代碼
websocket.onopen = function(){
setHtml('聊天室連接成功')
}
function sendMsg(){
//獲取輸入文本框中需要發(fā)送到聊天室中的消息
var msg = document.getElementById('chat').value;
//發(fā)送消息
websocket.send(msg);
}
//給發(fā)送按鈕綁定事件
document.getElementById('sendBtn').onclick = sendMsg;
//當(dāng)接收到服務(wù)端的消息時(shí),需要執(zhí)行的代碼
websocket.onmessage = function(e){
//將消息顯示出來
setHtml(e.data);
}
//有人下線時(shí)調(diào)用
websocket.onclose = function(){
setHtml('有人下線啦!');
}
//進(jìn)入聊天室發(fā)生錯(cuò)誤時(shí)調(diào)用
websocket.onerror = function(){
setHtml('發(fā)生錯(cuò)誤啦');
}
//當(dāng)窗口關(guān)閉時(shí),主動關(guān)閉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="發(fā)送" id="sendBtn"/>
<input type="button" value="下線" id="ulBtn"/>
<div id="message"></div>
</div>
</body>
</html>












點(diǎn)擊后:


聊天室 END
留給讀者思考的作業(yè) START
1、實(shí)現(xiàn)輸入賬號密碼后能夠保存賬號密碼的功能。(答案見上面的內(nèi)容)
2、洗一個(gè)茶杯需要3秒,總共洗5個(gè)(每隔3秒打印洗了第i個(gè)茶杯),燒開水需要10秒(10秒后打印水燒開了),請編寫一個(gè)程序,讓上面兩個(gè)任務(wù)同時(shí)運(yùn)行。

<!DOCTYPE html>??
<html>??
<head>??
<meta charset="UTF-8">??
<title>Insert title here</title>??
</head>??
<body>??
? ? <!-- web worker是運(yùn)行在后臺的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()">點(diǎn)擊我不會阻塞代碼</div>
? ? <br><br>??
? ? <script type="text/javascript">??
? ? ? ?var w;? ? ? ? ?
? ? ? ?function startWorker(){??
? ? ? ? ? ?if(typeof(Worker)!="undefined"){//瀏覽器支持web worker??
? ? ? ? ? ? ? ?if(typeof(w)=="undefined"){//w是未定義的,還沒有開始計(jì)數(shù)? ? ? ??
? ? ? ? ? ? ? ? ? ?w = new Worker("webworker.js");//創(chuàng)建一個(gè)Worker對象,利用Worker的構(gòu)造函數(shù)
? ? ? ? ? ? ? ? ? ? w2 = new Worker("webworker2.js");//創(chuàng)建一個(gè)Worker對象,利用Worker的構(gòu)造函數(shù)??
? ? ? ? ? ? ? ?}??
? ? ? ? ? ? ? ?//onmessage是Worker對象的properties??
? ? ? ? ? ? ? ?w.onmessage = function(event){//事件處理函數(shù),用來處理后端的web worker傳遞過來的消息??
? ? ? ? ? ? ? ? ? ?document.getElementById("result").innerHTML="洗了第"+event.data+"個(gè)杯子";?
? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ? ?if(event.data=="5"){w.terminate();//利用Worker對象的terminated方法,終止??
? ? ? ? ? w=undefined; }
? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ?};?
? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ?w2.onmessage = function(event){//事件處理函數(shù),用來處理后端的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);//定時(shí)任務(wù)??
? ?i = i + 1;??
? ?postMessage(i);//postMessage是Worker對象的方法,用于向html頁面回傳一段消息??
? ?
}??
timeCount();//加1計(jì)數(shù),每500毫秒調(diào)用一次??


var i = 0;??
function timeCount2(){??
?
?
? setTimeout("timeCount2()",1000);//定時(shí)任務(wù)??
? ?i = i+1;
? ?if(i==10){ postMessage("水燒開了!");//postMessage是Worker對象的方法,用于向html頁面回傳一段消息
? ?}
? ?
??
}??
timeCount2();//加1計(jì)數(shù),每500毫秒調(diào)用一次??

推薦:https://blog.csdn.net/xyf_coco/article/details/80606731
3、實(shí)現(xiàn)聊天室功能(答案見上面的內(nèi)容)
留給讀者思考的作業(yè) END