js的聊天室组件的封装
需求
1.聊天框,用户名,输入框,发送按钮
2.用户名,输入框同时有内容,才能成功点击发送
3.点击发送按钮后,聊天框中添加一条内容
4.别人发送的消息也能在一定时间内返回到聊天框中
效果图:
发送后效果图:
分析:
- 点击发送或者回车后调用ajax向服务器发送JSON数据
- 每隔0.5秒向服务器发送请求,返回数据
- 获取到数据后,用textArea=,每次返回数据都会覆盖前面的内容,如果这里用+=就会一直累加。
接口文档
发送方式 POST
数据类型 JSON
地址 http://10.9.65.224:4020
1、主动发消息给服务器
req
{
type:1
user:张三
msg:你好
}
res
[
{user:张三,msg:你好,time:当前时间},
{user:张三,msg:你好,time:当前时间},
{user:张三,msg:你好,time:当前时间},
{user:张三,msg:你好,time:当前时间},
{user:张三,msg:你好,time:当前时间},
]
2、主动获取聊天消息
req
{
type:2
}
res
[
{user:张三,msg:你好,time:当前时间},
{user:张三,msg:你好,time:当前时间},
{user:张三,msg:你好,time:当前时间},
{user:张三,msg:你好,time:当前时间},
{user:张三,msg:你好,time:当前时间},
]
聊天室组件分装:
import Utils from "./Utils.js";
export default class ChatIndex{
bool;
ip;
constructor(_bool,_ip){
this.bool=_bool;
this.ip=_ip;
this.elem=this.creatElem();
setInterval(e=>this.aniamtion(e),500)
document.addEventListener("keyup",e=>this.clickHandler(e));
}
appendTo(parent){
if(typeof parent==="string") parent=document.querySelector(parent);
parent.appendChild(this.elem);
}
creatElem(){
var div=Utils.ce("div",{
// position:"relative",
});
this.textArea=Utils.ce("textarea",{
resize: "none",
width: "880px",
height: "400px",
backgroundColor: "white",
display:"block",
})
this.user=Utils.ce("input",{
// position:"absolute",
// left:0,
// top:"401px",
float:"left",
display:"block",
width:"120px",
height: "30px",
textAlign: "center",
fontSize: "25px",
outline: "none",
verticalAlign: "middle",
})
this.user.setAttribute("name","user");
this.msg=Utils.ce("input",{
height: "30px",
textAlign: "left",
fontSize: "25px",
outline: "none",
borderRadius: "30px",
padding:" 0px 15px",
width: "650px",
verticalAlign: "middle",
float:"left",
display:"block",
})
this.msg.setAttribute("name","msg");
var btn=Utils.ce("button",{
width:"70px",
height: "30px",
borderRadius: "30px",
outline: "none",
float:"left",
display:"block",
})
btn.textContent="发送";
btn.addEventListener("click",e=>this.clickHandler(e));
div.appendChild(this.textArea);
div.appendChild(this.user);
div.appendChild(this.msg);
div.appendChild(btn);
return div;
}
clickHandler(e){
if(e.type==="keyup" && e.keyCode!==13) return;
if(this.user.value.trim().length===0 || this.msg.value.trim().length===0) return;
this.ajax({
type:1,
user:this.user.value,
msg:this.msg.value,
bool:this.bool
})
this.msg.value="";
}
ajax(data){
var xhr=new XMLHttpRequest();
xhr.addEventListener("load",e=>this.loadHandler(e));
xhr.open("POST",this.ip);
xhr.send(JSON.stringify(data));
}
aniamtion(){
this.ajax({type:2});
}
loadHandler(e){
if(this.bool) var str="----";
else var str="";
this.textArea.value=JSON.parse(e.currentTarget.response).reduce((value,item)=>{ //不能用+=
console.log(item);
value+=item.user+":"+item.msg+str+item.time+"\n";
return value;
},"")
this.textArea.scrollTop=this.textArea.scrollHeight;
}
}
服务器代码
var http=require("http");
var arr=[];
var querystring=require("querystring");
var server=http.createServer(function(req,res){
var data="";
req.on("data",function(_data){
data+=_data;
})
req.on("end",function(){
if(data.trim().length===0) data=req.url.split("?")[1];
else{
try{
data=JSON.parse(data);
}catch(error){
}
}
if(typeof data==="string"){
try{
data=querystring.parse(data);
}catch(error){
res.end("数据类型错误");
return;
}
}
if(!data){
res.end("数据类型错误");
return;
}
if(data.type===1){
if(arr.length>500) arr.shift();
var date=new Date();
time=date.getHours()+":"+date.getMinutes()+":"+date.getSeconds();
if(data.bool) arr.push({user:data.user,msg:data.msg,time:time});
else arr.push({user:data.user,msg:data.msg,time:""});
console.log(arr);
}
// console.log(arr);
res.writeHead(200,{
"content-type":"text/html;charset=utf-8",
"Access-Control-Allow-Origin":"*"
});
res.write(JSON.stringify(arr));
res.end();
})
})
server.listen(4003,"10.9.65.224",function(){
console.log("服务开启")
})
Utils.js是工具包
export default class Utils{
static time=0;
static ids=0;
static timeManage={};
static timeStart(){
if(Utils.time) return;
Utils.time=new Date().getTime();
}
static timeEnd(){
var t=new Date().getTime()-Utils.time;
Utils.time=0;
return t;
}
static ts(){
Utils.ids++;
Utils.timeManage[Utils.ids]=new Date().getTime();
return ids;
}
static te(id){
if(!Utils.timeManage[Utils.id]) return 0;
var t=new Date().getTime()-Utils.timeManage[Utils.id];
delete Utils.timeManage[Utils.id];
return t;
}
static randomColor(){
var col="#";
for(var i=0;i<6;i++){
col+=Math.floor(Math.random()*16).toString(16);
}
return col;
}
static random(min,max){
return Math.floor(Math.random()*(max-min)+min);
}
static ce(type,style,parent){
var elem=document.createElement(type);
if(style){
for(var prop in style){
elem.style[prop]=style[prop];
}
}
if(typeof parent==="string") parent=document.querySelector(parent);
if(parent) parent.appendChild(elem);
return elem;
}
static setStyle(styles){
var style=document.createElement("style");
document.head.appendChild(style);
var styleSheet=document.styleSheets[document.styleSheets.length-1];
for(var prop in styles){
Utils.addCss(styleSheet,prop,styles[prop]);
}
}
static addCss(styleSheet,selector,style){
var str=selector+" {";
for(var prop in style){
var value=style[prop]
prop=prop.replace(/([A-Z])/g,function($1){
return "-"+$1.toLowerCase();
})
str+=prop+":"+value+";"
}
str+=" }";
styleSheet.insertRule(str,styleSheet.cssRules.length);
}
static CSStoString(str){
return str.replace(/(?<=:)(.*?)(?=;)|-[a-z](?=.+:)|;/g,function(item){
if(item===";") return ","
if(item[0]==="-") return item[1].toUpperCase();
return "'"+item.trim()+"'";
});
}
// TODO 将CSS转换为对象
static CSStoObject(str){
str=Utils.CSStoString(str);
return str.split(",").reduce((value,item)=>{
item=item.replace(/\n/g,"");
var arr=item.split(":");
arr[0]=arr[0].replace(/\s/g,"");
if(arr[1]===undefined) return value;
arr[1]=arr[1].replace(/'/g,"");
value[arr[0]]=arr[1];
return value;
},{})
}
static getCookie(){
return document.cookie.split(/;\s*/).reduce((value,item)=>{
var arr=item.split("=");
value[arr[0]]=isNaN(arr[1]) ? arr[1] : Number(arr[1]);
return value;
},{})
}
static getCookieValue(key){
return Utils.getCookie()[key];
}
static setCookie(key,value,date){
if(!date){
document.cookie=`${key}=${value}`;
return;
}
document.cookie=`${key}=${value};expires=${date.toUTCString()}`;
}
static setCookies(obj,date){
for(var key in obj){
Utils.setCookie(key,obj[key],date);
}
}
// TODO 删除Cookie
static removeCookie(key){
Utils.setCookie(key,"",new Date());
}
static clearCookie(){
for(var key in Utils.getCookie()){
Utils.removeCookie(key);
}
}
}