用AJAX写的聊天室(和淘宝上的阿里巴巴很像的工具条)
用AJAX写的聊天室(和淘宝下的阿里巴巴很像的工具条)
(例子见下面下载……)
1:页面
单击好友显示好友列表(这里是虚拟的),单击好友弹出对话框。
2 css样式
3.请求发送到后台ChatServlet,ChatServlet调用ChatService
ChatService
ChatServlet
(例子见下面下载……)
1:页面
单击好友显示好友列表(这里是虚拟的),单击好友弹出对话框。
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <html> <head> <title>聊天</title> <link href="css.css" rel="stylesheet" type="text/css"> <script language="javascript" type="text/javascript"> var _IsMousedown = 0; var _ClickLeft = 0; var _ClickTop = 0; function moveInit(divID,evt) { _IsMousedown = 1; if(getBrowserType() == "NSupport") { return; } var obj = getObjById(divID); if(getBrowserType() == "fox") { _ClickLeft = evt.pageX - parseInt(obj.style.left); _ClickTop = evt.pageY - parseInt(obj.style.top); }else{ _ClickLeft = evt.x - parseInt(obj.style.left); _ClickTop = evt.y - parseInt(obj.style.top); } } function Move(divID,evt) { if(_IsMousedown == 0) { return; } var objDiv = getObjById(divID); if(getBrowserType() == "fox") { objDiv.style.left = evt.pageX - _ClickLeft; objDiv.style.top = evt.pageY - _ClickTop; } else{ objDiv.style.left = evt.x - _ClickLeft; objDiv.style.top = evt.y - _ClickTop; } } function stopMove() { _IsMousedown = 0; } function getObjById(id) { return document.getElementById(id); } function getBrowserType() { var browser=navigator.appName var b_version=navigator.appVersion var version=parseFloat(b_version) //alert(browser); if ((browser=="Netscape")) { return "fox"; } else if(browser=="Microsoft Internet Explorer") { if(version>=4) { return "ie4+"; } else { return "ie4-"; } } else { return "NSupport"; } } function showdiv1(){ var d=document.getElementById('subpanel'); d.style.display="block"; } function hiddendiv1(name){ var d=document.getElementById('subpanel'); d.style.display="none"; document.getElementById('movediv').style.display='block'; document.getElementById('user').innerHTML=name document.getElementById("speaker").value=name; } function hiddendiv2(){ document.getElementById('getmessage').onLoad=""; } </script> </head> <body onLoad="sendEmptyRequest();"> <div id="getmessage"></div> <div id="footpanel"> <ul id="mainpanel"> <li id="chatpanel"> <a href="#" class="chat" onClick="showdiv1()">在线好友(<em>6</em>)</a> <div class="subpanel" id="subpanel"> <h3><span> – </span>在线好友</h3> <ul> <li><a href="#" onClick="hiddendiv1('张三')"><img src="img/user.png" />张三</a></li> <li><a href="#" onClick="hiddendiv1('李四')"><img src="img/user.png" />李四</a></li> <li><a href="#" onClick="hiddendiv1('王五')"><img src="img/user.png" />王五</a></li> <li><a href="#" onClick="hiddendiv1('赵六')"><img src="img/user.png" />赵六</a></li> <li><a href="#" onClick="hiddendiv1('abc')"><img src="img/user.png" />abc</a></li> <li><a href="#" onClick="hiddendiv1('123')"><img src="img/user.png" />123</a></li> </ul> </div> </li> </ul> </div> <div id="movediv" style="left:20px;top:20px;" onMouseDown="moveInit('movediv',event);" onMouseMove="Move('movediv',event)" onMouseUp="stopMove()" onMouseOut="stopMove()"> <table style="width:376px; background-color: #f0f5fb;border:none; "> <tr> <td width="40%"> <span style="font-size:15px;"> 与<label id="user"></label>在线聊天中 </span> </td> <td width="30%" style="text-align:right;"> <span style="font-size:12px; font-style:Verdana;"><a href = "javascript:void(0)" onclick = "document.getElementById('movediv').style.display='none';">点这里关闭本窗口</a></span> </td> </tr> </table> <table id="$chat_table" style="width:376px; background-color: #f0f5fb; "> <tr> <td style="height:200px; width:100%;"> <div align="center"> <textarea id="chatArea" name="chatArea" cols="40" rows="15" readonly="readonly"></textarea> </div> </td> </tr> <tr> <td style="height:20px;text-align:right; vertical-align:middle; width: 100%;-moz-user-select: text;"> <div align="center"> <input id="chatMsg" name="chatMsg" type="text"size="40" onkeypress="enterHandler(event);"/> <input type="button" name="button" value="提交" onclick="ajaxSubmit();"/> <input type=hidden id="speaker" value=""> </div> </td> </tr> </table> </div> <script type="text/javascript"> var xmlHttpRequest = null;//声明一个变量来接受xmlHttpRequest对象 function ajaxSubmit() { if (window.ActiveXObject) {//这是IE浏览器 xmlHttpRequest=new ActiveXObject("Microsoft.XMLHTTP"); } else if (window.XMLHttpRequest) {//这是除IE外的其他浏览器 xmlHttpRequest = new XMLHttpRequest(); } if (xmlHttpRequest != null) { var v1 = document.getElementById("speaker").value; var v2 = document.getElementById("chatMsg").value; //POST请求,ChatServlet是servlet,true的是异步,false就是同步 xmlHttpRequest.open("POST", "${pageContext.servletContext.contextPath }/ChatServlet", true); xmlHttpRequest.onreadystatechange = ajaxCallback;//关联好ajax的回调方法 document.getElementById("chatMsg").value=""; xmlHttpRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded") xmlHttpRequest.send("user=" + v1 + "&chatMsg=" + v2); } } function sendEmptyRequest(){ if (window.ActiveXObject) { xmlHttpRequest=new ActiveXObject("Microsoft.XMLHTTP"); } else if (window.XMLHttpRequest) { xmlHttpRequest = new XMLHttpRequest(); } if (xmlHttpRequest != null) { xmlHttpRequest.open("POST", "${pageContext.servletContext.contextPath }/ChatServlet", true); xmlHttpRequest.onreadystatechange = ajaxCallback; xmlHttpRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded") xmlHttpRequest.send(null); //指定0.8s之后再次发送请求 setTimeout("sendEmptyRequest()" , 800); } } // 处理返回信息函数 function ajaxCallback() { //当XMLHttpRequest读取服务器响应完成 ReadyState共有5中状态(0,1,2,3,4) if (xmlHttpRequest.readyState == 4) { //服务器响应正确(当服务器响应正确时,返回值为200的状态码) if (xmlHttpRequest.status == 200) { //使用chatArea多行文本域显示服务器响应的文本 document.getElementById("chatArea").value = xmlHttpRequest.responseText; } //else //{ //提示页面不正常 // window.alert("您所请求的页面有异常。"); //} } } function enterHandler(event){ //获取用户单击键盘的“键值” var keyCode = event.keyCode ? event.keyCode : event.which ? event.which : event.charCode; //如果是回车键 if (keyCode == 13){ ajaxSubmit(); } } </script> </body> </html>
2 css样式
#footpanel { display: none; position: fixed; bottom: 0; left: 0; z-index: 9999; /*制作出一个斜面,让工具栏看起来更有层次感*/ background: #e3e2e2; border: 1px solid #c3c3c3; border-bottom: none; width: 370; margin: 0 975px 0; } *html #footpanel { /*IE6 Hack 让工具栏定位底部*/ margin-top: -1px; /*修正IE6工具栏滚动条的1像素误差*/ position: absolute; top:expression(eval(document.compatMode &&document.compatMode=='CSS1Compat') ?documentElement.scrollTop+(documentElement.clientHeight-this.clientHeight) : document.body.scrollTop +(document.body.clientHeight-this.clientHeight)); } #footpanel ul { padding: 0; margin: 0; float: left; width: 100%; list-style: none; border-top: 1px solid #fff; /*制作出一个斜面,让工具栏看起来更有层次感*/ font-size: 1em; line-height:1em; } #footpanel ul li{ padding: 0; margin: 0; float: left; position: relative; } #footpanel ul li a{ padding: 5px; float: left; text-indent: -9999px; height: 16px; width: 16px; text-decoration: none; color: #333; position: relative; } html #footpanel ul li a:hover{ background-color: #fff; } html #footpanel ul li a.active { /*当工具栏上的链接被点击,里面的菜单打开的状态*/ background-color: #fff; height: 17px; margin-top: -2px; /*在工具栏上向上提高2像素*/ border: 1px solid #555; border-top: none; z-index: 200; /*在工具栏上层显示*/ position: relative; } #footpanel a.chat{ background: url(balloon.gif) no-repeat 15px center; width: 126px; border-left: 1px solid #bbb; padding-left: 40px; text-indent: 0; /*将上面的文字位移去掉*/ } #footpanel li#chatpanel { float: right; } /*让好友列表居右显示*/ #footpanel a small { text-align: center; width: 70px; background: url(pop_arrow.gif) no-repeat center bottom; padding: 5px 5px 11px; display: none; /*默认状态为隐藏*/ color: #fff; font-size: 1em; text-indent: 0; } #footpanel a:hover small{ display: block; /*悬浮时显示*/ position: absolute; top: -35px; /*在工具栏上方35像素位置显示--*/ left: 50%; margin-left: -40px; /*居中*/ z-index: 9999; } #footpanel ul li div a { text-indent: 0;/*关键就是它*/ width: auto; height: auto; padding: 0; float: none; color: #00629a; position: static; } #footpanel ul li div a:hover { text-decoration: underline; } /*999*/ #footpanel .subpanel { position: absolute; left: 0; bottom: 27px; display: none; /*默认应为隐藏,但现在为了演示,将其设定为block,制作成功后应该为none*/ width: 125px; border: 1px solid #555; background: #fff; overflow: hidden; padding-bottom: 2px; } #footpanel h3 { background: #526ea6; padding: 5px 10px; color: #fff; font-size: 1.1em; cursor: pointer; } #footpanel h3 span { font-size: 1.5em; float: right; line-height: 0.6em; font-weight: normal; } #footpanel .subpanel ul{ padding: 0; margin: 0; background: #fff; width: 100%; overflow: auto; } #footpanel .subpanel li { float: none; /*取消上面定义的居左浮动-*/ display: block; padding: 0; margin: 0; overflow: hidden; clear: both; background: #fff; position: static; /*取消上面定义的相对定位*/ font-size: 1em; } #chatpanel .subpanel li a img { float: left;/*让图片居左显示*/ margin: 0 5px; } #chatpanel .subpanel li a{ padding: 3px 0; margin: 0; line-height: 22px; height: 22px; background: #fff; display: block;/*让链接呈块状显示,可点击区域变大*/ } #chatpanel .subpanel li a:hover { background: #3b5998; color: #fff; text-decoration: none; } #movediv{ display: none; width:100px; height:273px;position:absolute;border:1px solid #000;background:#EAEAEA; cursor:pointer; text-align:center; left:100px; top:10px; }
3.请求发送到后台ChatServlet,ChatServlet调用ChatService
ChatService
package com.happysys.im; import java.util.LinkedList; public class ChatService { //使用单例模式来设计ChatService private static ChatService cs; //使用LinkedList对象保存聊天信息 private LinkedList<String> chatMsg; //构造器私有 private ChatService() { } //通过静态方法返回唯一的ChatService对象 public static ChatService instance() { if (cs == null) { cs = new ChatService(); } return cs; } //获取系统中所有聊天信息 public String getMsg() { //如果chatMsg对象为null,表明不曾开始聊天 if (chatMsg == null) { chatMsg = new LinkedList<String>(); return ""; } StringBuilder result = new StringBuilder(""); //将chatMsg中所有聊天信息拼接起来。 for (String tmp : chatMsg) { result.append(tmp + "\n"); } return result.toString(); } //用户发言,添加聊天信息 public void addMsg(String user , String msg) { ///如果chatMsg对象为null,初始化chatMsg对象 if (chatMsg == null) { chatMsg = new LinkedList<String>(); } //最多保存40条聊天信息,当超过40条之后,将前面聊天信息删除 if (chatMsg.size() > 40) { chatMsg.removeFirst(); } //添加新的聊天信息 chatMsg.add("对"+user + "说:" + msg); } }
ChatServlet
package com.happysys.im; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ChatServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request,response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //设置使用UTF-8字符集来解析请求参数 //XMLHttpRequest所发送的POST请求默认采用UTF-8字符集 request.setCharacterEncoding("UTF-8"); String msg = request.getParameter("chatMsg"); System.out.println(msg); if ( msg != null && !msg.equals("")) { //取得当前用户 //String user = (String)request.getSession(true).getAttribute("user"); String user=request.getParameter("user"); //调用ChatService的addMsg来添加聊天消息 ChatService.instance().addMsg(user , msg); System.out.println(user); } //设置响应内容的类型 response.setContentType("text/html;charset=utf-8"); //获取页面输出流 PrintWriter out = response.getWriter(); //直接生成响应 out.println(ChatService.instance().getMsg()); } }